feat(memory): récolte automatique contrôlée de la mémoire (Lot E1)

Câble la récolte automatique de mémoire de bout en bout, sous contrôle
explicite, du domaine jusqu'à l'UI :

- domain : modèle `memory_harvest` (candidats de récolte, décision) +
  exports `lib.rs`.
- application : use case `memory/harvest` branché dans `memory/mod`,
  `lib.rs`, le cycle de vie d'agent (`agent/lifecycle`) et
  l'orchestrateur (`orchestrator/service`).
- app-tauri : wiring runtime dans `state`.
- frontend : DTO `domain/index` + hook `useMemory`.

Couverture : domain `memory_harvest` (14), application `memory_harvest`
(5) et `orchestrator_service` (récolte, 4), plus patch test-only du mock
gateway `workState` (`mock.test.ts`) et UI `memory.test`.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-21 02:00:05 +02:00
parent 33e65dec74
commit b12081be18
14 changed files with 1155 additions and 20 deletions

View File

@ -19,8 +19,8 @@ use application::{
DeleteLayout, DeleteMemory, DeleteProfile, DeleteSkill, DeleteTemplate,
DescribeEmbedderEngines, DetectAgentDrift, DetectProfiles, DismissEmbedderSuggestion,
FirstRunState, GetMemory, GetProjectPermissions, GetProjectWorkState, GitBranches, GitCheckout,
GitCommit, GitGraph, GitInit, GitLog, GitStage, GitStatus, GitUnstage, HealthUseCase,
InspectConversation, LaunchAgent, LaunchAgentInput, ListAgents, ListAgentsInput,
GitCommit, GitGraph, GitInit, GitLog, GitStage, GitStatus, GitUnstage, HarvestMemoryFromTurn,
HealthUseCase, InspectConversation, LaunchAgent, LaunchAgentInput, ListAgents, ListAgentsInput,
ListEmbedderProfiles, ListLayouts, ListMemories, ListProfiles, ListProjects,
ListResumableAgents, ListSkills, ListTemplates, LiveAgentRegistry, LiveSessions, LoadLayout,
McpRuntime, MoveTabToNewWindow, MutateLayout, OnnxModelView, OpenProject, OpenTerminal,
@ -1181,7 +1181,15 @@ impl AppState {
// ReadContext/ProposeContext/ReadMemory/WriteMemory derrière le garde partagé.
// Sans ça, `require_context_guard()` reste `None` ⇒ les outils MCP
// `idea_context_*`/`idea_memory_*` échouent pour tous les agents.
.with_context_guard(context_guard),
.with_context_guard(context_guard)
// Auto-memory harvest (Lot E1) : après le checkpoint Response d'un `ask`
// réussi, parse les blocs ` ```idea-memory ` de la réponse et persiste les
// notes valides via le `MemoryStore` (root par appel). Best-effort strict :
// un échec n'altère jamais la réponse/le ticket/le handoff.
.with_memory_harvest(Arc::new(HarvestMemoryFromTurn::new(
Arc::clone(&memory_store_port),
Arc::clone(&events_port),
))),
// NB (régression corrigée) : on ne câble PAS `.with_structured(...)` ici.
// Décision produit lot B-2 (« Option 1 Terminal + MCP », cf. construction
// de `LaunchAgent` plus haut) : la fabrique structurée est décâblée, donc