## Phase 8: Enterprise Extractor Improvements ✅ - 14 security extractors (TLS, JWT, SQL injection, XSS, etc.) - 10 framework-specific extractors (Spring, Django, Rails, etc.) - Config file security detection (YAML, TOML) ## Phase 9: Autonomous Extractor Generation ✅ - Shadow mode executor with TP/FP tracking - Graduation pipeline with confidence thresholds - Auto-rollback on regression detection - Cross-project pattern syncing ## UAT Suite Complete (14 scripts, 90 tests) - test-core-detection.sh (6 tests) - test-declarative-extractors.sh (5 tests) - test-domain-frameworks.sh (5 tests) - test-domain-unreal.sh (3 tests) - test-llm-extraction.sh (6 tests) - test-eval-harness.sh (5 tests) - test-cross-language.sh (3 tests) - test-precommit-performance.sh (4 tests) - test-output-formats.sh (8 tests) - test-drift-detection.sh (6 tests) - test-exit-codes.sh (12 tests) + 3 more scripts ## Other Changes - Updated roadmap to mark Phase 8-9 complete - Added .gitignore entries for build artifacts - Updated pre-commit: 800 line limit, exclude tests/data/cmd Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
96 lines
3.3 KiB
Rust
96 lines
3.3 KiB
Rust
//! Alias management for local Episteme operations.
|
|
//!
|
|
//! Handles auto-alias creation and manual alias management.
|
|
|
|
use stemedb_core::types::{AliasOrigin, ConceptAlias, ConceptPath};
|
|
use stemedb_storage::AliasStore;
|
|
use tracing::{debug, instrument};
|
|
|
|
use crate::AphoriaError;
|
|
|
|
use super::corpus::current_timestamp;
|
|
use super::local::LocalEpisteme;
|
|
|
|
impl LocalEpisteme {
|
|
/// Create an alias from a code path to an authoritative path, if it doesn't already exist.
|
|
///
|
|
/// This is used during conflict detection to persist the relationship between
|
|
/// code concepts and their authoritative counterparts.
|
|
#[instrument(skip(self), fields(code_path = %code_path, auth_path = %auth_path))]
|
|
pub async fn create_alias_if_new(
|
|
&self,
|
|
code_path: &str,
|
|
auth_path: &str,
|
|
agent_id: [u8; 32],
|
|
timestamp: u64,
|
|
) -> Result<(), AphoriaError> {
|
|
// Check if alias already exists
|
|
let existing = self.alias_store().get_canonical(code_path).await.map_err(|e| {
|
|
AphoriaError::Storage(format!("Failed to get canonical alias for {code_path}: {e}"))
|
|
})?;
|
|
|
|
if existing.is_some() {
|
|
debug!("Alias already exists, skipping");
|
|
return Ok(());
|
|
}
|
|
|
|
// Parse paths
|
|
let alias_path = ConceptPath::parse(code_path)
|
|
.map_err(|e| AphoriaError::Storage(format!("Invalid code path: {}", e)))?;
|
|
let canonical_path = ConceptPath::parse(auth_path)
|
|
.map_err(|e| AphoriaError::Storage(format!("Invalid auth path: {}", e)))?;
|
|
|
|
// Create and persist alias
|
|
let alias = ConceptAlias::new(
|
|
alias_path,
|
|
canonical_path,
|
|
agent_id,
|
|
timestamp,
|
|
AliasOrigin::AutoDetected,
|
|
);
|
|
|
|
self.alias_store().set_alias(&alias).await.map_err(|e| {
|
|
AphoriaError::Storage(format!(
|
|
"Failed to set alias from {code_path} to {auth_path}: {e}"
|
|
))
|
|
})?;
|
|
|
|
debug!("Created auto-detected alias");
|
|
Ok(())
|
|
}
|
|
|
|
/// Fetch manual aliases for policy export.
|
|
///
|
|
/// Returns all aliases stored in the local Episteme instance.
|
|
/// These can be auto-detected aliases from conflict detection or
|
|
/// manually created aliases.
|
|
pub async fn fetch_manual_aliases(&self) -> Result<Vec<ConceptAlias>, AphoriaError> {
|
|
let alias_tuples = self
|
|
.alias_store()
|
|
.list_all_aliases()
|
|
.await
|
|
.map_err(|e| AphoriaError::Storage(format!("Failed to list all aliases: {e}")))?;
|
|
|
|
let timestamp = current_timestamp();
|
|
let agent_id = self.agent_id();
|
|
|
|
// Convert (alias_str, canonical_str) tuples to ConceptAlias structs
|
|
let aliases = alias_tuples
|
|
.into_iter()
|
|
.filter_map(|(alias_str, canonical_str)| {
|
|
let alias_path = ConceptPath::parse(&alias_str).ok()?;
|
|
let canonical_path = ConceptPath::parse(&canonical_str).ok()?;
|
|
Some(ConceptAlias::new(
|
|
alias_path,
|
|
canonical_path,
|
|
agent_id,
|
|
timestamp,
|
|
AliasOrigin::Manual, // Treat all exported aliases as manual
|
|
))
|
|
})
|
|
.collect();
|
|
|
|
Ok(aliases)
|
|
}
|
|
}
|