From 554906ec02d2b6b643c9c8a732a50ec76ac30957 Mon Sep 17 00:00:00 2001 From: Hare Date: Mon, 24 Aug 2026 14:07:42 +0900 Subject: [PATCH] fix: treat legacy Runtime config as unconfigured --- .../workspace-server/src/runtime_settings.rs | 76 ++++++++++++++----- 1 file changed, 59 insertions(+), 17 deletions(-) diff --git a/crates/workspace-server/src/runtime_settings.rs b/crates/workspace-server/src/runtime_settings.rs index 0167647d..e7d8ac5c 100644 --- a/crates/workspace-server/src/runtime_settings.rs +++ b/crates/workspace-server/src/runtime_settings.rs @@ -44,23 +44,22 @@ pub fn project_runtime_from_workspace_config( workspace_id: &str, state: &WorkspaceConfigState, ) -> Result { - let bundle = if state.contract.schema_bundle.contributions.is_empty() { - config_source::WorkspaceConfigSchemaBundle::compose([ - RuntimeConfigSchemaProvider.contribution()? - ]) - .map_err(|error| Error::Config(error.to_string()))? - } else { - state.contract.schema_bundle.clone() - }; - let evaluation = evaluate_workspace_config_state(state, bundle)?; - if evaluation.projection_digest != state.projection_digest - && state - .contract - .schema_bundle - .contributions - .iter() - .any(|entry| entry.provider_id == "builtin:runtime") - { + let has_runtime_schema = state + .contract + .schema_bundle + .contributions + .iter() + .any(|entry| entry.provider_id == "builtin:runtime"); + if !has_runtime_schema { + return Ok(RuntimeConfigProjection { + config_revision: state.snapshot.revision, + projection_digest: state.projection_digest.clone(), + default_runtime_id: None, + }); + } + + let evaluation = evaluate_workspace_config_state(state, state.contract.schema_bundle.clone())?; + if evaluation.projection_digest != state.projection_digest { return Err(Error::RegistryInconsistency(format!( "Runtime projection digest mismatch for Workspace {workspace_id}" ))); @@ -155,6 +154,49 @@ mod tests { assert_eq!(projection.default_runtime_id, None); } + #[test] + fn runtime_projection_treats_pre_runtime_schema_bundle_as_unconfigured() { + let bundle = + config_source::WorkspaceConfigSchemaBundle::compose([ConfigSchemaContribution::new( + "builtin:legacy", + "legacy", + "1", + "{ legacy = { enabled = Bool default false; }; }", + ) + .unwrap()]) + .unwrap(); + let snapshot = ConfigTreeSnapshot::from_entries( + 6, + [ConfigEntry::new( + VirtualPath::parse("main.dcdl").unwrap(), + ConfigContentType::Decodal, + "{ legacy = { enabled = true; }; } as WorkspaceConfigSchema", + ) + .unwrap()], + ) + .unwrap(); + let contract = config_source::ToolchainContract::with_schema_bundle( + config_source::DEFAULT_SCHEMA_VERSION, + vec![VirtualPath::parse("main.dcdl").unwrap()], + config_source::DEFAULT_IMPORT_POLICY_VERSION, + bundle, + ); + let projection_digest = config_source::SnapshotEnvironment::new(snapshot.clone()) + .evaluate_contract(&contract) + .unwrap() + .projection_digest; + let state = WorkspaceConfigState { + snapshot, + contract, + projection_digest: projection_digest.clone(), + }; + + let projection = project_runtime_from_workspace_config("workspace", &state).unwrap(); + assert_eq!(projection.default_runtime_id, None); + assert_eq!(projection.config_revision, 6); + assert_eq!(projection.projection_digest, projection_digest); + } + #[test] fn runtime_schema_rejects_non_string_default() { let bundle =