fix(arch): unify TS/Rust types + classroom persistence registration + approval audit
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
- M11-03: Register ClassroomPersistence via Tauri .setup() hook with in-memory fallback. Previously missing — classroom commands would crash at runtime. - M3-02: Document BrowserHand as schema validator + TypeScript delegation passthrough (dual-path architecture explicitly documented). - M4-04: Add defense-in-depth audit logging in execute_hand() and execute_hand_with_source() when needs_approval hands bypass approval gate. - TYPE-01: Add #[serde(rename_all = "camelCase")] to Rust AgentInfo. Add missing fields to TS AgentInfo (messageCount, createdAt, updatedAt). Fix KernelStatus TS interface to match Rust KernelStatusResponse (baseUrl/model instead of defaultProvider/defaultModel). - SEC2-P1-01: Document EXTRACTION_DRIVER OnceCell as legacy path; Kernel struct field is the active path. - TriggerSource: Add #[derive(PartialEq)] for approval audit comparisons.
This commit is contained in:
@@ -227,28 +227,37 @@ impl LlmDriverForExtraction for TauriExtractionDriver {
|
||||
}
|
||||
}
|
||||
|
||||
/// Global extraction driver instance (lazy-initialized).
|
||||
/// Global extraction driver instance (legacy path, kept for compatibility).
|
||||
///
|
||||
/// **Architecture note:** The Kernel struct now holds its own `extraction_driver` field
|
||||
/// (set via `kernel.set_extraction_driver()`), which is the primary path used by
|
||||
/// the middleware chain. This OnceCell global is a legacy artifact — its accessors
|
||||
/// are dead code. The `configure_extraction_driver()` function is still called during
|
||||
/// kernel_init for backward compatibility but the primary consumption path is
|
||||
/// through the Kernel struct.
|
||||
static EXTRACTION_DRIVER: tokio::sync::OnceCell<Arc<TauriExtractionDriver>> =
|
||||
tokio::sync::OnceCell::const_new();
|
||||
|
||||
/// Configure the global extraction driver.
|
||||
/// Configure the global extraction driver (legacy path).
|
||||
///
|
||||
/// Call this during kernel initialization after the Kernel's LLM driver is available.
|
||||
/// Called during kernel initialization. The primary path is via
|
||||
/// `kernel.set_extraction_driver()` which stores the driver in the Kernel struct
|
||||
/// for use by the middleware chain.
|
||||
pub fn configure_extraction_driver(driver: Arc<dyn LlmDriver>, model: String) {
|
||||
let adapter = TauriExtractionDriver::new(driver, model);
|
||||
let _ = EXTRACTION_DRIVER.set(Arc::new(adapter));
|
||||
tracing::info!("[ExtractionAdapter] Extraction driver configured");
|
||||
tracing::info!("[ExtractionAdapter] Extraction driver configured (legacy OnceCell path)");
|
||||
}
|
||||
|
||||
/// Check if the extraction driver is available.
|
||||
/// Check if the extraction driver is available (legacy OnceCell path).
|
||||
#[allow(dead_code)]
|
||||
pub fn is_extraction_driver_configured() -> bool {
|
||||
EXTRACTION_DRIVER.get().is_some()
|
||||
}
|
||||
|
||||
/// Get the global extraction driver.
|
||||
/// Get the global extraction driver (legacy OnceCell path).
|
||||
///
|
||||
/// Returns `None` if not yet configured via `configure_extraction_driver`.
|
||||
/// Prefer accessing via `kernel.extraction_driver()` when the Kernel is available.
|
||||
#[allow(dead_code)]
|
||||
pub fn get_extraction_driver() -> Option<Arc<TauriExtractionDriver>> {
|
||||
EXTRACTION_DRIVER.get().cloned()
|
||||
|
||||
@@ -123,6 +123,28 @@ pub fn run() {
|
||||
.manage(classroom_chat_state)
|
||||
.manage(classroom_gen_tasks)
|
||||
.manage(kernel_commands::mcp::McpManagerState::default())
|
||||
.setup(|app| {
|
||||
// Initialize classroom persistence (async SQLite + data loading).
|
||||
// Must complete before the event loop starts so that classroom
|
||||
// commands have a valid persistence layer available.
|
||||
use tauri::Manager;
|
||||
let classroom_store = app.state::<classroom_commands::ClassroomStore>().inner().clone();
|
||||
let chat_store = app.state::<classroom_commands::ChatStore>().inner().clone();
|
||||
let handle = app.handle().clone();
|
||||
|
||||
let rt = tokio::runtime::Runtime::new()
|
||||
.expect("Failed to create runtime for classroom persistence init");
|
||||
|
||||
let persistence = rt.block_on(
|
||||
classroom_commands::init_persistence(&handle, &classroom_store, &chat_store)
|
||||
).unwrap_or_else(|e| {
|
||||
tracing::error!("[Classroom] Persistence init failed: {}, using in-memory fallback", e);
|
||||
rt.block_on(classroom_commands::persist::ClassroomPersistence::open_in_memory())
|
||||
.expect("In-memory SQLite should never fail")
|
||||
});
|
||||
app.manage(persistence);
|
||||
Ok(())
|
||||
})
|
||||
.invoke_handler(tauri::generate_handler![
|
||||
// Internal ZCLAW Kernel commands (preferred)
|
||||
kernel_commands::lifecycle::kernel_init,
|
||||
|
||||
@@ -275,8 +275,8 @@ export class KernelClient {
|
||||
return {
|
||||
initialized: status.initialized,
|
||||
agentCount: status.agentCount,
|
||||
defaultProvider: status.defaultProvider,
|
||||
defaultModel: status.defaultModel,
|
||||
defaultProvider: status.baseUrl,
|
||||
defaultModel: status.model,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -13,8 +13,8 @@ export interface KernelStatus {
|
||||
initialized: boolean;
|
||||
agentCount: number;
|
||||
databaseUrl: string | null;
|
||||
defaultProvider: string | null;
|
||||
defaultModel: string | null;
|
||||
baseUrl: string | null;
|
||||
model: string | null;
|
||||
}
|
||||
|
||||
// === Agent Types ===
|
||||
@@ -23,9 +23,12 @@ export interface AgentInfo {
|
||||
id: string;
|
||||
name: string;
|
||||
description?: string;
|
||||
model: string;
|
||||
provider: string;
|
||||
state: string;
|
||||
model?: string;
|
||||
provider?: string;
|
||||
messageCount: number;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface CreateAgentRequest {
|
||||
|
||||
Reference in New Issue
Block a user