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
6 changes: 6 additions & 0 deletions scripts/core-boundaries/rules/feature-rules.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,12 @@ export const productCoreFeatureAssemblyRules = [
requiredFeatures: ['product-full'],
reason: 'CLI must explicitly assemble the full bitfun-core product runtime',
},
{
manifestPath: 'src/apps/server/Cargo.toml',
dependencyName: 'bitfun-core',
requiredFeatures: ['product-full'],
reason: 'Server must explicitly assemble the full bitfun-core product runtime',
},
{
manifestPath: 'src/crates/interfaces/acp/Cargo.toml',
dependencyName: 'bitfun-core',
Expand Down
96 changes: 96 additions & 0 deletions scripts/core-boundaries/rules/source/public-api-rules.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const publicApiContractSlices = [
'external-source-tool-contract',
'external-source-subagent-contract',
'external-source-mcp-contract',
'external-integration-policy-contract',
];

const contractSlices = {
Expand All @@ -20,6 +21,7 @@ const contractSlices = {
externalSourceToolContract: 'external-source-tool-contract',
externalSourceSubagentContract: 'external-source-subagent-contract',
externalSourceMcpContract: 'external-source-mcp-contract',
externalIntegrationPolicyContract: 'external-integration-policy-contract',
};

function pluginRuntimeEntry(symbol, p0, consumer, verification, contractSlice, wireImpact = true) {
Expand Down Expand Up @@ -230,6 +232,55 @@ function externalSourceEntry(symbol, owner, consumer, wireImpact = false) {
};
}

function externalIntegrationPolicyEntry(
symbol,
owner = 'product-domains external integration policy contract owner',
consumer = 'bitfun-core product composition and cross-host product surfaces',
wireImpact = true,
) {
return {
symbol,
owner,
consumer,
verification:
'external integration policy contract tests, core policy lifecycle tests, cross-host route tests, and Web policy-control tests',
p0: 'host-owned external integration policy and OpenCode-compatible product defaults',
contractSlice: contractSlices.externalIntegrationPolicyContract,
wireImpact,
rationale:
'all product surfaces need one ecosystem-neutral, versioned, fail-closed policy contract while concrete ecosystem defaults remain in product assembly',
exit:
'remove only through a reviewed policy-contract migration with equivalent compatibility, safety-ceiling, and cross-host behavior tests',
};
}

export const externalIntegrationPolicyPublicApiEntries = [
'EXTERNAL_INTEGRATION_POLICY_SCHEMA_MAJOR',
'ExternalIntegrationMode',
'ExternalIntegrationAccess',
'ExternalEcosystemPolicy',
'ExternalIntegrationPolicySettings',
'ExternalIntegrationPolicySettingsView',
'ExternalEcosystemPolicyOverride',
'ExternalEcosystemPolicyOverrideView',
'ExternalIntegrationPolicyOverride',
'ExternalIntegrationPolicyOverrideView',
'ExternalIntegrationPolicyDocument',
'ExternalIntegrationCapabilityDescriptor',
'ExternalIntegrationEcosystemDescriptor',
'ExternalEcosystemPolicyView',
'EffectiveExternalEcosystemPolicy',
'EffectiveExternalIntegrationPolicy',
'ExternalIntegrationPolicyStatus',
'ExternalIntegrationPolicySnapshot',
'ExternalIntegrationPolicyScope',
'ExternalIntegrationPolicyOperation',
'ExternalIntegrationPolicyMutation',
'evaluate_external_integration_policy',
'external_integration_policy_snapshot',
'incompatible_external_integration_policy_snapshot',
].map((symbol) => externalIntegrationPolicyEntry(symbol));

function externalToolEntry(symbol, owner, consumer, wireImpact = false) {
return {
symbol,
Expand Down Expand Up @@ -298,6 +349,9 @@ export const externalSourceContractPublicApiEntries = [
'ExternalSourceContext',
'ExternalWatchRoot',
'ExternalSourceProviderError',
'ExternalSourceOperationErrorCode',
'ExternalSourceOperationError',
'ExternalSourceOperationResult',
'PromptCommandSourceProvider',
'ExternalSourceLifecycleState',
'ExternalSourceCatalogEntry',
Expand All @@ -306,6 +360,10 @@ export const externalSourceContractPublicApiEntries = [
'PromptCommandConflict',
'prompt_command_conflict_key',
'ExternalSourceCatalogSnapshot',
'ExternalPromptCommandDefinitionSummary',
'ExternalPromptCommandSummary',
'ExternalSourcePublicSnapshot',
'ExternalSourceHostCapabilities',
].map((symbol) =>
externalSourceEntry(
symbol,
Expand Down Expand Up @@ -459,6 +517,30 @@ export const externalSourceCoordinatorPublicApiEntries = [
];

export const externalSourceCorePublicApiEntries = [
...[
'ExternalIntegrationAccess',
'ExternalIntegrationMode',
'ExternalIntegrationPolicyMutation',
'ExternalIntegrationPolicyOperation',
'ExternalIntegrationPolicyScope',
'EffectiveExternalIntegrationPolicy',
'ExternalIntegrationPolicySnapshot',
'ExternalIntegrationPolicyStatus',
'EcosystemId',
'ExternalIntegrationCapabilityId',
'EXTERNAL_CAPABILITY_COMMAND',
'EXTERNAL_CAPABILITY_TOOL',
'EXTERNAL_CAPABILITY_SUBAGENT',
'EXTERNAL_CAPABILITY_MCP',
'update_external_integration_policy',
].map((symbol) =>
externalIntegrationPolicyEntry(
symbol,
'bitfun-core external integration policy composition facade',
'bitfun-cli, Desktop, Server, Peer Host, and Web API adapters',
true,
),
),
...[
'ExpandedPromptCommand',
'ExternalSourceCatalogEntry',
Expand All @@ -467,6 +549,10 @@ export const externalSourceCorePublicApiEntries = [
'ExternalSourceDiagnostic',
'ExternalSourceDiagnosticSeverity',
'ExternalSourceLifecycleState',
'ExternalSourceHostCapabilities',
'ExternalSourceOperationError',
'ExternalSourceOperationErrorCode',
'ExternalSourceOperationResult',
'PromptCommandAvailability',
'PromptCommandCatalogEntry',
'PromptCommandDefinition',
Expand All @@ -476,10 +562,13 @@ export const externalSourceCorePublicApiEntries = [
'remember_external_source_conflict_choice',
'set_external_prompt_command_conflict_choice',
'external_source_snapshot',
'external_source_read_only_snapshot',
'set_external_source_enabled',
'expand_external_prompt_command',
'sanitize_external_source_operation_error',
'subscribe_external_source_updates',
'ExternalSourceSubscription',
'ExternalSourcePublicSnapshot',
].map((symbol) =>
externalSourceEntry(
symbol,
Expand All @@ -493,6 +582,7 @@ export const externalSourceCorePublicApiEntries = [
'ExternalToolCapability',
'ExternalToolCatalogEntry',
'ExternalToolConflict',
'ExternalToolConflictCandidateKind',
'ExternalToolRuntimeKind',
'set_external_tool_target_decision',
'set_external_tool_conflict_choice',
Expand Down Expand Up @@ -657,6 +747,12 @@ export const publicApiAllowlistRules = [
'managed plugin package and trust contracts must stay explicitly budgeted and ecosystem-neutral',
allowedSymbolEntries: pluginSourceContractPublicApiEntries,
},
{
path: 'src/crates/contracts/product-domains/src/external_integration_policy.rs',
reason:
'external integration policy contracts must stay ecosystem-neutral, versioned, fail-closed, and explicitly consumer-backed',
allowedSymbolEntries: externalIntegrationPolicyPublicApiEntries,
},
{
path: 'src/crates/contracts/product-domains/src/external_sources.rs',
reason:
Expand Down
13 changes: 10 additions & 3 deletions scripts/core-boundaries/self-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ export function runManifestParserSelfTest({
for (const manifestPath of [
'src/apps/desktop/Cargo.toml',
'src/apps/cli/Cargo.toml',
'src/apps/server/Cargo.toml',
'src/crates/interfaces/acp/Cargo.toml',
]) {
if (!productCoreRulePaths.has(manifestPath)) {
Expand Down Expand Up @@ -195,15 +196,21 @@ export function runManifestParserSelfTest({
},
{
manifestPath: 'src/apps/server/Cargo.toml',
text: '[dependencies]\naxum = { workspace = true }',
text:
'[dependencies]\nbitfun-core = { path = "../../crates/assembly/core", default-features = false, features = ["product-full"] }',
},
{
manifestPath: 'src/crates/interfaces/acp/Cargo.toml',
text: '[dependencies."bitfun-core"]\npath = "../../assembly/core"\ndefault-features = false\nfeatures = ["product-full"]',
},
]);
if (discoveredProductCoreManifests.join(',') !== 'src/apps/desktop/Cargo.toml,src/crates/interfaces/acp/Cargo.toml') {
throw new Error('product core dependency scanner must discover only manifests that depend on bitfun-core');
if (
discoveredProductCoreManifests.join(',') !==
'src/apps/desktop/Cargo.toml,src/apps/server/Cargo.toml,src/crates/interfaces/acp/Cargo.toml'
) {
throw new Error(
'product core dependency scanner must discover only manifests that depend on bitfun-core',
);
}
const ownerFeatureRulePaths = new Set(
ownerCrateFeatureAssemblyRules.map((rule) => rule.manifestPath),
Expand Down
Loading
Loading