Skip to content

Commit 6759d78

Browse files
committed
feat(indexer): extract L1 identity facts after indexing
Wire VaultProfile through the indexer call chain (run_index -> run_index_inner, run_index_shared) and call extract_l1_facts at the end of each index run. The profile is loaded once in run_index and passed through, eliminating redundant load_vault_profile calls for exclude patterns and people detection. In the watcher, both startup reconciliation and full rescan pass the profile from the existing Arc<Option<VaultProfile>> context.
1 parent 44dafc0 commit 6759d78

2 files changed

Lines changed: 20 additions & 7 deletions

File tree

src/indexer.rs

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::config::Config;
1313
use crate::docid::generate_docid;
1414
use crate::graph::extract_wikilink_targets;
1515
use crate::llm::EmbedModel;
16+
use crate::profile::VaultProfile;
1617
use crate::store::{FileRecord, Store};
1718

1819
/// Summary of an indexing run.
@@ -459,7 +460,8 @@ pub fn run_index(vault_path: &Path, config: &Config, rebuild: bool) -> Result<In
459460
// Store current dimension for future checks
460461
store.set_meta("embedding_dim", &model_dim.to_string())?;
461462

462-
run_index_inner(vault_path, config, &store, &mut embedder, rebuild)
463+
let profile = crate::config::Config::load_vault_profile().ok().flatten();
464+
run_index_inner(vault_path, config, &store, &mut embedder, rebuild, profile.as_ref())
463465
}
464466

465467
/// Like [`run_index`], but accepts shared `Store` and `Embedder` references.
@@ -472,8 +474,9 @@ pub fn run_index_shared(
472474
store: &Store,
473475
embedder: &mut impl EmbedModel,
474476
rebuild: bool,
477+
profile: Option<&VaultProfile>,
475478
) -> Result<IndexResult> {
476-
run_index_inner(vault_path, config, store, embedder, rebuild)
479+
run_index_inner(vault_path, config, store, embedder, rebuild, profile)
477480
}
478481

479482
/// Shared implementation for [`run_index`] and [`run_index_shared`].
@@ -483,6 +486,7 @@ fn run_index_inner(
483486
store: &Store,
484487
embedder: &mut impl EmbedModel,
485488
rebuild: bool,
489+
profile: Option<&VaultProfile>,
486490
) -> Result<IndexResult> {
487491
let start = Instant::now();
488492

@@ -498,8 +502,8 @@ fn run_index_inner(
498502

499503
// Build exclude list: config excludes + archive folder (if detected)
500504
let mut exclude = config.exclude.clone();
501-
if let Ok(Some(profile)) = crate::config::Config::load_vault_profile()
502-
&& let Some(archive) = &profile.structure.folders.archive
505+
if let Some(p) = profile
506+
&& let Some(archive) = &p.structure.folders.archive
503507
{
504508
let archive_pattern = format!("{}/", archive);
505509
if !exclude.contains(&archive_pattern) {
@@ -599,8 +603,8 @@ fn run_index_inner(
599603
}
600604

601605
// People detection (if configured via vault profile)
602-
if let Ok(Some(profile)) = crate::config::Config::load_vault_profile()
603-
&& let Some(people_folder) = &profile.structure.folders.people
606+
if let Some(p) = profile
607+
&& let Some(people_folder) = &p.structure.folders.people
604608
{
605609
let people = load_people_entities(store, people_folder, &content_by_path)?;
606610
if !people.is_empty() {
@@ -663,6 +667,13 @@ fn run_index_inner(
663667
store.upsert_folder_centroid(folder, &centroid, vectors.len())?;
664668
}
665669

670+
// Extract L1 identity facts from the freshly indexed vault
671+
if let Some(p) = profile {
672+
if let Err(e) = crate::identity::extract_l1_facts(store, p) {
673+
tracing::warn!("L1 identity extraction failed (non-fatal): {e:#}");
674+
}
675+
}
676+
666677
let duration = start.elapsed();
667678
info!(
668679
new = new_files.len(),

src/watcher.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub fn start_watcher(
5353
&store_lock,
5454
&mut *embedder_lock,
5555
false,
56+
profile_clone.as_ref().as_ref(),
5657
) {
5758
tracing::warn!("Startup reconciliation failed: {:#}", e);
5859
}
@@ -302,7 +303,7 @@ pub async fn run_consumer(
302303
store: Arc<Mutex<Store>>,
303304
embedder: Arc<Mutex<Box<dyn EmbedModel + Send>>>,
304305
vault_path: Arc<PathBuf>,
305-
_profile: Arc<Option<VaultProfile>>,
306+
profile: Arc<Option<VaultProfile>>,
306307
config: Config,
307308
recent_writes: RecentWrites,
308309
) {
@@ -625,6 +626,7 @@ pub async fn run_consumer(
625626
&store_guard,
626627
&mut *embedder_guard,
627628
false,
629+
profile.as_ref().as_ref(),
628630
) {
629631
Ok(result) => {
630632
tracing::info!(

0 commit comments

Comments
 (0)