diff --git a/src/catalog_transaction.rs b/src/catalog_transaction.rs index c5173358..130782a1 100644 --- a/src/catalog_transaction.rs +++ b/src/catalog_transaction.rs @@ -1812,7 +1812,9 @@ fn project_raw_current(root: &Path) -> Result { let mut files = BTreeMap::new(); add_optional_regular(root, &root.join(crate::catalog::CONFIG_FILE), &mut files)?; let spec_paths = collect_canonical_specs(root, ProjectionSource::Current, &mut files)?; - let workspace_dirs = raw_workspace_dirs(root, &spec_paths)?; + // Invalid declarations cannot establish typed workspace facts; canonical runtime directories + // are excluded structurally by the shared bundle collector instead. + let workspace_dirs = BTreeSet::new(); for spec in &spec_paths { let bundle = spec.parent().context("canonical spec has no bundle")?; collect_bundle_files( @@ -1834,30 +1836,6 @@ fn project_raw_current(root: &Path) -> Result { }) } -fn raw_workspace_dirs(root: &Path, spec_paths: &[PathBuf]) -> Result> { - let mut workspace_dirs = BTreeSet::new(); - for spec in spec_paths { - let bundle = spec.parent().context("canonical spec has no bundle")?; - let workspace = bundle.join(".workspace"); - match fs::symlink_metadata(&workspace) { - Ok(metadata) => { - anyhow::ensure!( - metadata.is_dir() && !metadata.file_type().is_symlink(), - "canonical workspace fact is not a real directory: {}", - workspace.display() - ); - workspace_dirs.insert(normalized_relative(root, &workspace)?); - } - Err(error) if error.kind() == std::io::ErrorKind::NotFound => {} - Err(error) => { - return Err(error) - .with_context(|| format!("inspect workspace fact {}", workspace.display())); - } - } - } - Ok(workspace_dirs) -} - fn project( root: &Path, source: ProjectionSource, diff --git a/tests/catalog_apply.rs b/tests/catalog_apply.rs index fc8a17a2..77e4e998 100644 --- a/tests/catalog_apply.rs +++ b/tests/catalog_apply.rs @@ -1901,6 +1901,12 @@ profile "dev.example.observe" {{ ) .unwrap(); fs::write(agent.join("status"), "busy").unwrap(); + fs::create_dir_all(agent.join(".workspace")).unwrap(); + fs::write( + agent.join(".workspace/session.txt"), + "preserve live workspace", + ) + .unwrap(); let raw_capture_dir = temp.path().join("raw-capture-legacy"); let captured = raw_snapshot(&catalog, &raw_capture_dir); @@ -1914,6 +1920,7 @@ profile "dev.example.observe" {{ fs::read_to_string(raw_capture_dir.join("catalog.kdl")).unwrap(), legacy_config ); + assert!(!raw_capture_dir.join("agents/host/worker/.workspace").exists()); let desired = temp.path().join("desired-component"); write_agent(&desired, "worker", false); @@ -1958,6 +1965,10 @@ profile "dev.example.observe" {{ "preserve mutable context" ); assert_eq!(fs::read_to_string(agent.join("status")).unwrap(), "busy"); + assert_eq!( + fs::read_to_string(agent.join(".workspace/session.txt")).unwrap(), + "preserve live workspace" + ); let applied = st2::catalog::load(&catalog).unwrap(); assert_eq!(applied.pty_root.as_deref(), Some(pty_root)); assert_eq!(