
HiddenSteps — una piattaforma local-first di intelligence personale per i flussi di lavoro
Questo è il complemento onesto, allo stato attuale, della mappa dei moduli target di docs/design/02-system-architecture.md. Indica cosa è effettivamente costruito, cosa è verificato contro un backend reale rispetto a un mock e cosa manca ancora davvero — non cosa è pianificato (quello è in docs/roadmap/01-implementation-roadmap.md).
Esegui cargo build --workspace && cargo test --workspace && cargo clippy --workspace --all-targets -- -D warnings dalla radice del repository. Al momento della stesura: 12 crate, 193 test superati, zero warning clippy, cargo fmt --check pulito — 183 nelle 11 crate che non richiedono display o servizi esterni, più 10 in hiddensteps-observation che richiedono un display X11 attivo (verificato dove presente; vedi quella riga). Quattro test sono contrassegnati con #[ignore] di proposito (vedi sotto) e non sono conteggiati né come fallimenti né come parte dei 193.
| Crate | Implementa | Come verificato |
|---|---|---|
hiddensteps-domain | Tipi fondamentali: PrivacyLevel/PrivacyState, EventSummary/SignalType, Pattern, Recommendation, AuditEntry e CapturedSignal — un tipo che strutturalmente non può essere persistito (nessun Serialize), applicando la regola dei dati grezzi di ADR-0006 a livello di tipo | Test unitari: round-trip/ordinamento dei livelli, gating TTL della Deep Mode |
hiddensteps-security | SecretStore (ADR-0008): vault di sistema reale (KeyringSecretStore) + implementazioni in-memory (di test); generazione della chiave master CSPRNG (restituita in un wrapper zeroize::Zeroizing così la chiave viene azzerata al drop invece di rimanere nella memoria liberata); derivazione della passphrase Argon2id per la Portable Mode (PassphraseKey azzera la chiave derivata al drop, conservando il salt non segreto). Allo stesso modo hiddensteps-event-store conserva il testo SQL PRAGMA key/rekey contenente la chiave in Zeroizing | Test unitari contro lo store in-memory e il KDF; il round trip con il vault reale è contrassegnato con #[ignore] (vedi sotto) |
hiddensteps-event-store | SqlCipherEventStore (ADR-0003): lo schema completo da docs/design/07-database-schema.md, CRUD per stato della privacy, eventi, registro di audit, pattern, collegamenti pattern↔evento, embedding dei pattern (vedi nota sotto), raccomandazioni, configurazione del provider LLM e impostazioni generiche, più delete_all_data (transazionale; esegue anche un rekey per un "cancella tutto" che sopravvive a un riavvio)/export_data/count_rows (diagnostica)/delete_expired_events (la pulizia TTL della Deep Mode, chiamata dal loop periodico di raccomandazioni di apps/desktop/src-tauri — ttl_expires_at veniva persistito dalla v0.1.0 ma prima d'ora nulla eliminava una riga oltre quella scadenza); applicazione delle foreign key (PRAGMA foreign_keys = ON) così che l'ON DELETE CASCADE di schema.sql sui collegamenti pattern↔evento venga effettivamente eseguito | 33 test contro un file SQLCipher reale: la chiave sbagliata non apre il file, la stessa chiave riapre correttamente, delete-all pulisce ogni tabella incluse le più recenti, il round trip di rekey funziona, la pulizia TTL lascia intatti gli eventi non scaduti, il delete a cascata non lascia collegamenti pattern↔evento orfani |
hiddensteps-redaction | Il motore di redazione (docs/design/05-privacy-model.md §4): rilevatori regex+Luhn per chiavi API/token/chiavi PEM/email/SSN/carte di credito, un rilevatore di segreti ambigui basato sull'entropia e la politica di eliminazione in caso di incertezza | 30 test, inclusi input deliberatamente avversari (segreti incorporati in testo, non-segreti molto vicini come gli SHA di git, SSN senza trattini o con spazi, numeri di carta con cifre di padding, token ad alta entropia tutti nella stessa maiuscola/minuscola) |
hiddensteps-pipeline | La pipeline degli eventi (ADR-0006): Classifica → Redigi → Riassumi, gating per livello di privacy in base al tipo di segnale, assegnazione TTL della Deep Mode | 8 test che coprono eliminazioni innescate dalla redazione, eliminazioni per gating di livello e riassunzione riuscita |
hiddensteps-observation | ObservationSource (ADR-0005) + Linux: ActiveWindowSource (X11 GetInputFocus), FileOperationSource (inotify tramite notify), ClipboardMetadataSource (selezione X11, solo metadati), GlobalShortcutSource (X11 XGrabKey). Più i file sorgente per macOS/Windows (vedi sotto) | 10 test su 11 eseguiti contro backend reali in questo ambiente — un display X11 attivo (il DISPLAY=:0 di WSLg) e inotify reale, non mock. 1 test (la cattura reale di GlobalShortcutSource) è contrassegnato con #[ignore] di proposito |
hiddensteps-llm-provider | LlmProvider (ADR-0004): client Ollama (con un campo di richiesta think: Option<bool> per i modelli di ragionamento ibrido), un client compatibile con il wire di OpenAI (copre OpenAI/Azure/OpenRouter/Together/Groq/DeepSeek/LocalAI), un client Anthropic Messages e auto-rilevamento del runtime locale. Ogni client imposta un timeout di richiesta (build_http_client) così che un remoto bloccato non possa bloccare una chiamata per sempre; Ollama inoltra max_tokens come suo options.num_predict annidato | 19 test contro server mock wiremock (incluso un controllo reale che il timeout scatti e che Ollama invii effettivamente num_predict), più 2 test di integrazione con Ollama reale (tests/ollama_live.rs, contrassegnati con #[ignore] — vedi sotto) che hanno trovato e corretto un problema reale: lo stesso prompt impiegava oltre due minuti contro un vero modello locale di ragionamento ibrido con think lasciato al default, e pochi secondi con think: Some(false) |
hiddensteps-patterns | Rilevamento dei pattern (matching di sequenze n-gram a finestra scorrevole) + Grafo del flusso di lavoro (grafo di transizione con pesi sugli archi) — Livello 1 di ADR-0010 | 16 test, incluso un analogo diretto dell'esempio "observed 31 times" dello stesso PROMPT.md e un test di regressione che verifica che finestre sovrapposte su una ripetizione continua non vengano conteggiate due volte |
hiddensteps-recommendations | Il Livello 2 del motore di raccomandazioni (ADR-0010): sintesi LLM con un contratto di prompt JSON strutturato, un validatore di contraddizioni narrative e un loop di retry — fondamentalmente, i campi numerici (estimated_time_saved_minutes) non vengono mai parsati dall'output dell'LLM, ma solo calcolati dal Livello 1 | 23 test, inclusi retry su JSON malformato, retry per contraddizione narrativa (che coprono i numeri scritti in lettere e ogni campo controllato dall'LLM, non solo why) ed estrazione JSON consapevole delle stringhe, contro un provider di test scriptato |
hiddensteps-privacy-engine | Il gate di invio al cloud (docs/design/03-data-flow-diagrams.md §5) e il versionamento del consenso (docs/design/05-privacy-model.md §5); PrivacyGatedProvider incapsula qualsiasi LlmProvider così che il gate non possa essere aggirato dal normale percorso di chiamata | 13 test, incluso che il contenuto di Livello 4 sia bloccato anche con ogni consenso concesso |