commit 30b7eb3ff07dc3c1f7c302c2959e56ec793dbb07
parent 7774f24d1bdcff4c23d83d41e822c8ec9180fdd9
Author: triesap <tyson@radroots.org>
Date: Fri, 3 Jul 2026 06:40:17 +0000
runtime: remove migration startup report
- drop runtime migration contract fields from startup reporting
- remove legacy path inspection from path contract output
- replace migration tests with canonical path contract coverage
- keep daemon startup logging on active runtime paths only
Diffstat:
2 files changed, 29 insertions(+), 98 deletions(-)
diff --git a/src/app/paths.rs b/src/app/paths.rs
@@ -1,12 +1,10 @@
use std::path::{Path, PathBuf};
-use anyhow::{Context, Result};
+use anyhow::Result;
use radroots_runtime_paths::{
- DEFAULT_CONFIG_FILE_NAME, DEFAULT_SERVICE_IDENTITY_FILE_NAME, RadrootsLegacyPathCandidate,
- RadrootsMigrationReport, RadrootsPathProfile, RadrootsPathResolver,
- RadrootsRuntimeMigrationContract, RadrootsRuntimePathSelection,
- RadrootsRuntimeSelectionContract, RadrootsRuntimeSelectionOverrideContract,
- inspect_legacy_paths, runtime_migration_contract,
+ DEFAULT_CONFIG_FILE_NAME, DEFAULT_SERVICE_IDENTITY_FILE_NAME, RadrootsPathProfile,
+ RadrootsPathResolver, RadrootsRuntimePathSelection, RadrootsRuntimeSelectionContract,
+ RadrootsRuntimeSelectionOverrideContract,
};
use serde::Serialize;
@@ -22,7 +20,6 @@ const SUBORDINATE_PATH_OVERRIDE_KEYS: [&str; 2] = [
"config.service.logs_dir",
"config.publish_proxy.database_path",
];
-const MIGRATION_IMPORT_HINT: &str = "stop the runtime, inspect this legacy path, then perform an explicit import or manual copy into the canonical destination; radrootsd will not move it on startup";
#[derive(Debug, Clone, PartialEq, Eq)]
pub(crate) struct RadrootsdRuntimePaths {
@@ -39,14 +36,12 @@ pub struct RadrootsdRuntimeContractOutput {
pub path_overrides: RadrootsdRuntimePathOverrideContractOutput,
pub default_shared_secret_backend: String,
pub allowed_shared_secret_backends: Vec<String>,
- pub migration: RadrootsdRuntimeMigrationContractOutput,
pub canonical_config_path: PathBuf,
pub canonical_logs_dir: PathBuf,
pub canonical_identity_path: PathBuf,
pub canonical_publish_proxy_database_path: PathBuf,
}
-pub type RadrootsdRuntimeMigrationContractOutput = RadrootsRuntimeMigrationContract;
pub type RadrootsdRuntimePathOverrideContractOutput = RadrootsRuntimeSelectionOverrideContract;
pub(crate) fn process_path_selection() -> Result<(RadrootsPathProfile, Option<PathBuf>)> {
@@ -149,7 +144,6 @@ fn runtime_contract_with_selection(
.into_iter()
.map(str::to_owned)
.collect(),
- migration: runtime_migration_contract(RadrootsMigrationReport::empty()),
canonical_config_path: paths.config_path,
canonical_logs_dir: paths.logs_dir,
canonical_identity_path: paths.identity_path,
@@ -157,53 +151,6 @@ fn runtime_contract_with_selection(
})
}
-#[allow(dead_code)]
-pub(crate) fn runtime_migration_for_process(
- contract: &RadrootsdRuntimeContractOutput,
-) -> Result<RadrootsdRuntimeMigrationContractOutput> {
- let current_dir = std::env::current_dir().context("resolve current directory")?;
- Ok(runtime_migration_for_current_dir(
- contract,
- current_dir.as_path(),
- ))
-}
-
-pub(crate) fn runtime_migration_for_current_dir(
- contract: &RadrootsdRuntimeContractOutput,
- current_dir: &Path,
-) -> RadrootsdRuntimeMigrationContractOutput {
- let report = inspect_legacy_paths(legacy_path_candidates(contract, current_dir));
- migration_contract_output(report)
-}
-
-fn legacy_path_candidates(
- contract: &RadrootsdRuntimeContractOutput,
- current_dir: &Path,
-) -> Vec<RadrootsLegacyPathCandidate> {
- vec![
- RadrootsLegacyPathCandidate::new(
- "radrootsd_repo_config_v0",
- "legacy radrootsd repo-relative config",
- current_dir.join(DEFAULT_CONFIG_FILE_NAME),
- Some(contract.canonical_config_path.clone()),
- MIGRATION_IMPORT_HINT,
- ),
- RadrootsLegacyPathCandidate::new(
- "radrootsd_repo_logs_v0",
- "legacy radrootsd repo-relative logs directory",
- current_dir.join("logs"),
- Some(contract.canonical_logs_dir.clone()),
- MIGRATION_IMPORT_HINT,
- ),
- ]
-}
-
-fn migration_contract_output(
- report: RadrootsMigrationReport,
-) -> RadrootsdRuntimeMigrationContractOutput {
- runtime_migration_contract(report)
-}
-
#[cfg(test)]
mod tests {
use std::path::PathBuf;
@@ -212,7 +159,7 @@ mod tests {
RadrootsHostEnvironment, RadrootsPathProfile, RadrootsPathResolver, RadrootsPlatform,
};
- use super::{runtime_contract_with_resolver, runtime_migration_for_current_dir};
+ use super::runtime_contract_with_resolver;
fn linux_resolver() -> RadrootsPathResolver {
RadrootsPathResolver::new(
@@ -225,13 +172,7 @@ mod tests {
}
#[test]
- fn runtime_migration_detects_legacy_repo_relative_state_without_moving_it() {
- let temp = tempfile::tempdir().expect("tempdir");
- std::fs::write(
- temp.path().join("config.toml"),
- "[metadata]\nname = \"old\"\n",
- )
- .expect("write old config");
+ fn runtime_contract_output_contains_canonical_runtime_paths() {
let contract = runtime_contract_with_resolver(
&linux_resolver(),
RadrootsPathProfile::InteractiveUser,
@@ -239,19 +180,29 @@ mod tests {
)
.expect("contract");
- let report = runtime_migration_for_current_dir(&contract, temp.path());
-
- assert_eq!(report.posture, "explicit_operator_import_required");
- assert_eq!(report.state, "legacy_state_detected");
- assert!(!report.silent_startup_relocation);
- assert_eq!(report.detected_legacy_paths.len(), 1);
+ assert_eq!(contract.active_profile, "interactive_user");
+ assert_eq!(
+ contract.allowed_profiles,
+ ["interactive_user", "service_host", "repo_local"]
+ );
+ assert_eq!(contract.path_overrides.root_source, "host_defaults");
+ assert_eq!(
+ contract.canonical_config_path,
+ PathBuf::from("/home/treesap/.radroots/config/services/radrootsd/config.toml")
+ );
+ assert_eq!(
+ contract.canonical_logs_dir,
+ PathBuf::from("/home/treesap/.radroots/logs/services/radrootsd")
+ );
assert_eq!(
- report.detected_legacy_paths[0].id,
- "radrootsd_repo_config_v0"
+ contract.canonical_identity_path,
+ PathBuf::from(
+ "/home/treesap/.radroots/secrets/services/radrootsd/identity.secret.json"
+ )
);
assert_eq!(
- report.detected_legacy_paths[0].destination,
- Some(contract.canonical_config_path)
+ contract.canonical_publish_proxy_database_path,
+ PathBuf::from("/home/treesap/.radroots/data/services/radrootsd/publish_proxy.sqlite")
);
}
}
diff --git a/src/app/runtime.rs b/src/app/runtime.rs
@@ -61,7 +61,6 @@ struct RadrootsdRuntimeStartupReport {
publish_proxy_database_path_source: String,
canonical_publish_proxy_database_path: PathBuf,
path_overrides: paths::RadrootsdRuntimePathOverrideContractOutput,
- migration: paths::RadrootsdRuntimeMigrationContractOutput,
default_shared_secret_backend: String,
allowed_shared_secret_backends: Vec<String>,
}
@@ -156,7 +155,6 @@ fn runtime_startup_report(
args: &cli::Args,
settings: &config::Settings,
contract: &paths::RadrootsdRuntimeContractOutput,
- migration: paths::RadrootsdRuntimeMigrationContractOutput,
) -> RadrootsdRuntimeStartupReport {
RadrootsdRuntimeStartupReport {
active_profile: contract.active_profile.clone(),
@@ -205,7 +203,6 @@ fn runtime_startup_report(
.canonical_publish_proxy_database_path
.clone(),
path_overrides: contract.path_overrides.clone(),
- migration,
default_shared_secret_backend: contract.default_shared_secret_backend.clone(),
allowed_shared_secret_backends: contract.allowed_shared_secret_backends.clone(),
}
@@ -240,10 +237,6 @@ fn log_runtime_startup_report(report: &RadrootsdRuntimeStartupReport) {
repo_local_root = ?report.path_overrides.repo_local_root,
repo_local_root_source = ?report.path_overrides.repo_local_root_source,
subordinate_path_override_source = report.path_overrides.subordinate_path_override_source.as_str(),
- migration_posture = report.migration.posture.as_str(),
- migration_state = report.migration.state.as_str(),
- migration_detected_legacy_paths = report.migration.detected_legacy_paths.len(),
- silent_startup_relocation = report.migration.silent_startup_relocation,
config_path = %report.config_path.display(),
config_path_source = report.config_path_source.as_str(),
canonical_config_path = %report.canonical_config_path.display(),
@@ -440,9 +433,7 @@ pub async fn run() -> Result<()> {
#[cfg(not(test))]
{
let contract = paths::runtime_contract_for_process().context("resolve runtime contract")?;
- let migration =
- paths::runtime_migration_for_process(&contract).context("inspect runtime migration")?;
- let report = runtime_startup_report(&args, &settings, &contract, migration);
+ let report = runtime_startup_report(&args, &settings, &contract);
log_runtime_startup_report(&report);
}
@@ -613,13 +604,6 @@ mod tests {
},
default_shared_secret_backend: "encrypted_file".to_string(),
allowed_shared_secret_backends: vec!["encrypted_file".to_string()],
- migration: paths::RadrootsdRuntimeMigrationContractOutput {
- posture: "explicit_operator_import_required".to_string(),
- state: "ready".to_string(),
- silent_startup_relocation: false,
- compatibility_window: "detect_and_report_only".to_string(),
- detected_legacy_paths: Vec::new(),
- },
canonical_config_path: PathBuf::from(
"/home/treesap/.radroots/config/services/radrootsd/config.toml",
),
@@ -854,8 +838,7 @@ mod tests {
PathBuf::from("/tmp/radrootsd/publish_proxy.sqlite");
let contract = sample_runtime_contract();
- let report =
- runtime_startup_report(&args, &settings, &contract, contract.migration.clone());
+ let report = runtime_startup_report(&args, &settings, &contract);
assert_eq!(
report,
@@ -882,7 +865,6 @@ mod tests {
"/home/treesap/.radroots/data/services/radrootsd/publish_proxy.sqlite"
),
path_overrides: sample_runtime_contract().path_overrides,
- migration: sample_runtime_contract().migration,
default_shared_secret_backend: "encrypted_file".to_string(),
allowed_shared_secret_backends: vec!["encrypted_file".to_string()],
}
@@ -905,8 +887,7 @@ mod tests {
settings.config.publish_proxy.database_path =
contract.canonical_publish_proxy_database_path.clone();
- let report =
- runtime_startup_report(&args, &settings, &contract, contract.migration.clone());
+ let report = runtime_startup_report(&args, &settings, &contract);
assert_eq!(report.config_path, contract.canonical_config_path);
assert_eq!(report.config_path_source, "profile_default");
@@ -920,7 +901,6 @@ mod tests {
);
assert_eq!(report.publish_proxy_database_path_source, "profile_default");
assert_eq!(report.path_overrides, contract.path_overrides);
- assert_eq!(report.migration, contract.migration);
assert_eq!(report.default_shared_secret_backend, "encrypted_file");
assert_eq!(
report.allowed_shared_secret_backends,