diff --git a/Cargo.lock b/Cargo.lock
index 306fc5cf74..3ce0f0c1eb 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6027,6 +6027,7 @@ dependencies = [
"tracedecay-code-index",
"tracedecay-configuration",
"tracedecay-contracts",
+ "tracedecay-daemon-protocol",
"tracedecay-domain",
"tracedecay-global-db",
"tracedecay-graph-db",
@@ -6158,6 +6159,7 @@ dependencies = [
"tracedecay-api",
"tracedecay-application",
"tracedecay-automation-runtime",
+ "tracedecay-configuration",
"tracedecay-contracts",
"tracedecay-daemon-control",
"tracedecay-daemon-identity",
@@ -6310,8 +6312,10 @@ dependencies = [
name = "tracedecay-configuration"
version = "0.1.0"
dependencies = [
+ "glob",
"hex",
"hotpath",
+ "serde",
"serde_json",
"sha2 0.11.0",
"tempfile",
@@ -6321,6 +6325,7 @@ dependencies = [
"tracedecay-contracts",
"tracedecay-domain",
"tracedecay-global-db",
+ "tracedecay-lcm",
"tracedecay-policy",
"tracedecay-runtime-core",
"tracedecay-semantic-contracts",
diff --git a/crates/tracedecay-application/Cargo.toml b/crates/tracedecay-application/Cargo.toml
index 40c238d94a..bf99585e5c 100644
--- a/crates/tracedecay-application/Cargo.toml
+++ b/crates/tracedecay-application/Cargo.toml
@@ -67,6 +67,7 @@ url = "2"
zeroize = "1.9.0"
tracedecay-contracts = { path = "../tracedecay-contracts", version = "0.1.0" }
tracedecay-automation = { path = "../tracedecay-automation", version = "0.1.0" }
+tracedecay-daemon-protocol = { path = "../tracedecay-daemon-protocol", version = "0.1.0" }
# Grammar-free entry only: `markdown_structure` compiles with no language
# feature enabled, so section structure reaches retrieval without linking a
# tree-sitter bundle into this crate.
diff --git a/crates/tracedecay-application/src/lib.rs b/crates/tracedecay-application/src/lib.rs
index e028ad9c4f..1dc75e57a9 100644
--- a/crates/tracedecay-application/src/lib.rs
+++ b/crates/tracedecay-application/src/lib.rs
@@ -84,6 +84,7 @@ pub mod observation;
pub mod operation_stream;
pub mod pr_tracking;
pub mod primitives;
+pub mod project_adoption;
pub mod project_open_authorization;
pub mod semantic_runtime;
pub mod settings_control;
diff --git a/crates/tracedecay/src/tracedecay/lifecycle/adoption.rs b/crates/tracedecay-application/src/project_adoption.rs
similarity index 68%
rename from crates/tracedecay/src/tracedecay/lifecycle/adoption.rs
rename to crates/tracedecay-application/src/project_adoption.rs
index a192015767..8430c2926d 100644
--- a/crates/tracedecay/src/tracedecay/lifecycle/adoption.rs
+++ b/crates/tracedecay-application/src/project_adoption.rs
@@ -27,13 +27,10 @@
use std::path::{Path, PathBuf};
use tracedecay_daemon_protocol::MovedStoreAdoption;
-
use tracedecay_domain::errors::{Result, TraceDecayError};
use tracedecay_global_db::RegisteredGlobalDb;
use tracedecay_runtime_core::storage::{self, StoreLayout};
-use super::TraceDecay;
-
#[derive(Debug, Clone, PartialEq, Eq)]
struct MovedNongitCandidate {
project_id: String,
@@ -51,114 +48,111 @@ enum MovedStoreEvidence {
NoMatch,
}
-impl TraceDecay {
- /// Remaps a moved non-git project onto `project_root` under an explicit
- /// operator adoption decision.
- ///
- /// Returns `Ok(None)` when adoption was not requested or there is no
- /// moved-store candidate, so first-touch may mint a new identity.
- /// Ambiguous or conflicting adoption is a typed refusal, never an alias.
- #[hotpath::measure(label = "lifecycle.adopt_moved_nongit", future = true)]
- pub(crate) async fn adopt_moved_nongit_project(
- project_root: &Path,
- profile_root: &Path,
- registry: &RegisteredGlobalDb,
- adoption: &MovedStoreAdoption,
- ) -> Result