Le scrollback de ChatBridge croissait sans limite, faisant enfler la mémoire sur
les conversations longues. Il sert de buffer de replay transport (reattach), pas
d'historique durable.
Introduit un double cap : MAX_CHAT_SCROLLBACK_CHUNKS=2000 et
MAX_CHAT_SCROLLBACK_BYTES=512 KiB. Un helper trim_scrollback, appelé après chaque
send_output, drop des chunks entiers par la tête tout en conservant l'ordre et
les chunks les plus récents. Doc de chat.rs corrigée pour refléter cette nature
de buffer borné.
Aucun changement de ReplyChunk / reattach_agent_chat / DTO. Tests : suite
chat_bridge 19/19.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Épurement de la dette de ticket_list sur deux axes :
Recherche texte — matching exact du numéro/#ref via parse_issue_search_ref,
court-circuité avant load_issue, sans matching par substring numérique
(« 1 » ne remonte plus « 12 », « 123 »…).
Pagination — curseur opaque et stable anchor-based au lieu d'un offset fragile :
token v1.<base64url-no-pad-json> encodant le tri + l'ancre {number, sortKey},
reprise strictement après l'ancre. Curseur legacy / invalide / de version
inconnue / avec sort divergent rejeté par une erreur explicite « Invalid
cursor ». Le DTO cursor reste String → non-breaking côté UI.
Fichiers : infrastructure/src/issues.rs, app-tauri/src/tickets.rs,
app-tauri/Cargo.toml (+ base64 0.22). Tests : issue_store_text_filter,
ticket_list_ 7/7 (anchor-based + rejets).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Un profil structuré rencontrant une factory de session non câblée retombait
silencieusement sur pty.spawn (fallthrough du `if let`), masquant une erreur de
configuration au lieu de la signaler.
Remplace ce fallthrough par une intention explicite :
- nouvel enum StructuredRoutingMode { HumanPtyFallback, RequireStructured } sur
LaunchAgent, posé via le builder with_structured_routing_mode ;
- le `if let` devient un `match` explicite (agent/lifecycle.rs) ; en mode
RequireStructured, un profil structuré sans factory câblée retourne
AppError::Process("structured profile requires structured session factory")
au lieu de tomber sur pty.spawn.
Composition root (app-tauri/src/state.rs) : launcher humain = HumanPtyFallback,
launcher orchestrateur = RequireStructured, wake background rebranché sur
orchestrator_launch_agent.
Tests : agent_lifecycle.rs (4 branches de routage) + non-régression
agent_wake/structured_launch_d3. Crate application verte.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Stretch B2/F2 de #54, par-dessus le MVP déjà mergé (B1/F1).
Backend : le port de téléchargement HF publie une progression débouncée
(bytes reçus / total, pourcentage) via le stream de statut du serveur
modèle, avec gestion du total inconnu (pas de faux %), du cache hit,
de l'annulation et du timeout.
Frontend : l'overlay plein-cellule de préparation du serveur affiche la
progression réelle (barre, %, octets, source) en mappant le fil de
statut, avec la règle « pas de faux % » quand le total est inconnu.
Tests : application + infrastructure (téléchargement débouncé, cancel,
timeout, cache hit, total inconnu) et vitest (overlay + formatage pur).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ajoute un handle du téléchargement des modèles lors du démarrage de
llamacpp : le domaine et l'application émettent la progression de
téléchargement du modèle, relayée en événement côté app-tauri, et l'UI
l'affiche via un badge de lancement et un overlay de cellule pendant que
le serveur de modèle démarre.
Backend (B1) : progression de téléchargement dans domain/application,
relais d'événement app-tauri, couverture de tests.
Frontend (F1) : modelServerLaunch, badge et overlay LayoutGrid, tests.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ajoute la commande Tauri `list_open_view_windows` qui retourne un
`ViewWindowSnapshot` (panel, label, visible) par fenêtre de panneau
détachée, avec le parseur `view_panel_from_window_label` (labels stables
et legacy suffixés du project id). Enregistre la commande dans le
handler. Backend seul pour le ticket #50 ; pas encore de consommateur
frontend.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sur le rendez-vous délégué (idea_ask_agent), quand la cible touchait sa
limite de session, l'événement AgentRateLimited n'était pas émis : l'écart
backend documenté (ticket #7/F2) laissait la surface UI sans signal de
limite pour la cible déléguée.
Le service orchestrateur relaie désormais la limite de la cible vers le
service de limite de session, fermant l'écart en cohérence avec le chemin
direct (#30).
Couverture QA (sortie réelle) : orchestrator_service 63 passed,
session_limit_service 15 passed, session_limit_t4 7 passed,
cargo test -p application 0 failed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Le handle de limite de session ne se déclenchait pas quand un agent
directement adressé (dont Main) touchait sa propre limite : le ReplyEvent
::RateLimited du chemin structuré direct n'était pas relayé au service de
limite.
On tap désormais ReplyEvent::RateLimited dans le registre terminal vers
SessionLimitService::on_rate_limited, qui émet AgentRateLimited puis
AgentResumeScheduled et arme la reprise auto annulable, exactement comme le
chemin délégué.
Couverture QA (sortie réelle) : structured_registry_d1 12 passed,
session_limit_wiring 6 passed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Partie backend. Les fenêtres/panneaux détachés étaient restaurés avec un
project_id figé au moment du détachement, si bien qu'ils restaient collés à
un projet mort ou incohérent après redémarrage. Ils sont désormais restaurés
en mode panel-only, sans project_id figé, et suivent le projet en focus de la
fenêtre principale via un event focused-project exposé par la couche fenêtre.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
L'assistant IA d'édition de ticket éditait les fichiers du ticket en direct,
hors de tout contrôle. Il passe désormais par les tools MCP idea_ticket_* :
préparation d'un environnement structuré dédié et policy d'enforcement scopée
au ticket courant, de sorte que l'assistant ne peut agir que sur son ticket
via la surface MCP plutôt que sur le système de fichiers.
Couvert par de nouveaux tests QA (mcp_server, assistant_context_store).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Persiste l'état des fenêtres (layout/position) et le restaure au
relancement de l'application. Découpage hexagonal :
- domaine : modèle et port d'état des fenêtres (layout, ports)
- application : use cases de persistance/restauration
- infrastructure : store window_state (adapter de persistance)
- présentation : câblage app-tauri (state, commands, lib)
Couvert par des tests ciblés domaine/application/infrastructure.
Depend de #39 (fermeture des fenêtres auxiliaires).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ajoute close_non_main_webview_windows sur l'event de fermeture de la
fenêtre principale, avec le prédicat should_close_with_main_window qui
exclut la fenêtre "main" et cible toutes les fenêtres auxiliaires
(vues détachées, settings…). Couvert par 3 tests unitaires.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Backend du support natif d'une source modèle Hugging Face en alternative au
chemin .gguf local pour le serveur llama.cpp intégré, et refonte des options.
- domaine : ModelSource {LocalPath|HuggingFace} + HfModelRef,
LlamaCppOptions {host,gpu_layers,context_size,jinja}, invariant auto_start
exigeant une source, validate_free_args (rejet des flags réservés).
- infra : build_argv partagé avec build_spawn_spec, émission -hf vs --model,
ordre argv figé ; migration model-servers.json V1 -> V2.
- app-tauri : DTO V2 (modelSource, compat modelPath, conflit = INVALID),
commande preview_model_server_command.
QA : cargo test ciblés verts (domain 7, application 8, infra model_server 4,
app-tauri dto 5). Échecs des suites complètes infra/app-tauri environnementaux
(sandbox bind/socket), hors périmètre.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Le first-run wizard restait figé : `CliAgentRuntime::detect` construisait un
runtime tokio courant-thread via `futures_block_on` pour piloter un
`ProcessSpawner` async. Appelé depuis le runtime async de Tauri, ce
`block_on` imbriqué panique ; la commande IPC ne répond alors jamais, la
promesse `detectProfiles` reste pendante et `busy` ne redescend plus.
Ce commit s'attaque à la cause côté backend :
- `AgentRuntime::detect` devient `async fn` (`#[async_trait]`) : le port cesse
de mentir sur sa nature. Il pilote un spawner async, il est async. Le
`futures_block_on` disparaît, et avec lui le runtime imbriqué.
- La sonde CLI est bornée par `tokio::time::timeout(DETECTION_TIMEOUT)` :
un binaire qui ne rend jamais la main dégrade la détection en `Err`, il
ne gèle plus l'appelant.
- Les profils `StructuredAdapter::OpenAiCompatible` n'ont pas de CLI à
spawner : les sonder revenait à tester un binaire inexistant. Ils sont
désormais sondés par un GET HTTP sur l'endpoint `/models` dérivé de
`chat_http.endpoint`, borné par le même timeout.
`DetectProfiles` séquence les `await` sur les candidats. Les fakes
`AgentRuntime` des crates application/infrastructure/app-tauri suivent la
nouvelle signature.
Tests: cargo test -p domain (241), -p application (81), -p infrastructure
(269), -p app-tauri (63+15) — verts. `rg futures_block_on crates` sans match.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Détache les vues dans de vraies fenêtres système Tauri (multi-écran,
fullscreen). Backend : commandes de gestion de WebviewWindow, capabilities
et composition root. Frontend : nouveau port WindowGateway et son adaptateur
window, entrée panel-only ViewWindow/ViewPanelBody, détachement câblé dans
ProjectsView. QA vert : app-tauri 63, frontend typecheck + vitest 546/546.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ajoute le paramètre de tri dans TicketListQuery et l'expose via
ticket_list (surface app-tauri + MCP). Ports et adaptateur mock
frontend alignés sur le contrat de tri. La partie UI (contrôle de tri
dans TicketFacetsBar) suivra dans un commit frontend dédié.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Passe les filtres de la liste des tickets en sélection multiple (#12).
Backend Rust :
- IssueListFilter : statuses/priorities en Vec, filter_matches en OR intra-champ
et AND inter-champs
- TicketListRequestDto en tableaux + from_request (parse/déduplication)
- MCP idea_ticket_list aligné sur le nouveau contrat
Frontend :
- TicketListQuery.statuses/priorities
- UI de cases à cocher, toggle/clear des filtres
Tests verts : issue_store (7), app-tauri --lib (59), mcp_server (24),
issue_usecases (6), sprint_usecases (6), frontend vitest (505), npm run build (exit 0).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ajoute la suppression complète d'un ticket (#6).
Backend Rust :
- port IssueStore::delete (NotFound si absent) + event IssueDeleted{freed_sprint}
- FsIssueStore::delete : supprime .ideai/tickets/<N>/ et l'index sous lock
- use case DeleteIssue + adaptations des tests sprint/ticket_assistant au port
- commande Tauri ticket_delete + câblage events/state/lib
Frontend :
- gateway delete (ports, adapter ticket + mock, domain)
- useTicketDetail : retrait de la liste et fermeture du détail via event issueDeleted
- intégration TicketDetail + tests
Tests verts : application/issue_usecases (6), infrastructure/issue_store (7),
app-tauri --lib (56), frontend vitest (503), npm run build (exit 0).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ticket #10 — introduction du modèle de sprints côté backend.
- Domaine : nouvel agrégat Sprint (sprint.rs), IDs, événements et invariants ;
rattachement des issues à un sprint (issue.rs) et ports associés.
- Application : use-cases sprints (application/src/sprints) + erreurs dédiées.
- Infrastructure : store de sprints (infrastructure/src/sprints.rs), adaptation
du store d'issues et exposition MCP via orchestrator/mcp/tickets.rs.
- app-tauri : commandes, state et events pour piloter les sprints depuis l'UI.
Tests domaine/application/infra/app-tauri verts (sprint_usecases, sprint_store,
issue_store, mcp_server).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Redémarre le ticket #4 sur la base develop. Émission d'annonces live d'un
agent vers l'UI, distinctes du Final de délégation :
- domain: ReplyEvent::Announcement/Final et DomainEvent::AgentAnnouncement
(events.rs), port d'émission (ports.rs), gating de readiness (readiness.rs).
- application: mapping des événements structurés en annonces
(agent/structured.rs, agent/mod.rs, lib.rs) et relais côté orchestrateur
(orchestrator/service.rs).
- infrastructure/session: parse des annonces + fix du Final pour Claude et
Codex, propagé aux adaptateurs et à la conformance
(claude.rs, codex.rs, conformance.rs, mod.rs, process.rs, sandbox_e2e.rs).
- app-tauri: relais Tauri des annonces vers le front (events.rs, chat.rs).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
T1 — Wake automatique du propriétaire à la complétion.
La complétion d'une tâche de fond est désormais livrée à l'agent
propriétaire dès que la session accepte l'envoi (wake.rs :
mark_completion_delivered au send accepté), via un drain de flux dédié
(structured.rs : drain_reply_stream_with_readiness). L'inbox médiée
enfile l'item sans démarrer de tour ni marquer l'agent busy
(input/mod.rs : enqueue FIFO silencieux). Régression couverte
(tests/agent_wake.rs, tests input/mod.rs).
T3 — Tâches de fond projetées dans le read-model du panneau Work.
AgentWorkState porte désormais background_tasks
(VO AgentBackgroundTaskState), alimenté par un builder best-effort
with_background_tasks(store) : union list_open_for_agent + dispatch des
completions non livrées par owner_agent_id, erreur store => Vec vide
(aucune régression live/busy/tickets). DTO Tauri backgroundTasks et
wiring du BackgroundTaskStore côté state.rs. Le frontend, déjà câblé,
affiche Cancel/Retry (mapping queued/waiting -> pending, tri sur
updatedAtMs). Borne V1 : une tâche terminale déjà livrée n'est plus
énumérable (Retry limité à la fenêtre non livrée).
Tests : cargo build --workspace OK ; cargo test -p application /
-p app-tauri / -p infrastructure verts ; frontend build + vitest verts.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Intègre le système de tickets/issues V1 (validé QA vert de bout en bout,
mémoire tickets-v1-e2e-validated-qa) dans la branche des tâches de fond.
Conflits résolus : app-tauri/state.rs, domain/events.rs, domain/lib.rs, domain/ports.rs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Livre le lot backend B8 des tâches de fond :
- infrastructure : runner de commandes concret (CommandBackgroundRunner)
sur le port BackgroundTaskRunner, tail borné (bounded_tail/BoundedTail),
éclatement du module background_task en sous-modules (mod/runner/tail,
sink extrait de l'ancien background_task.rs).
- application : nouveau module background exposant les cas d'usage
SpawnBackgroundCommand, CancelBackgroundTask, RetryBackgroundTask et le
port BackgroundCommandArchive.
- domain : refactor point-2 de l'arbitrage Architect — sortie du trait
BackgroundCommandArchive de la couche domaine vers application.
- app-tauri : câblage runtime (commands, dto, state, lib) des commandes
spawn/cancel/retry et de la boucle de complétion sink fermée en
composition root.
Build workspace + tests application/infrastructure verts (QA).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Branche le store de tâches de fond dans le runtime : store per-root
routé par project_id, AppReconcileBackgroundTasks au boot,
AppWakeSessionProvider et boucle ready→MediatedInbox→AgentWakeService,
avec .with_background_tasks(store, clock) au builder OrchestratorService.
open_project appelle reconcile_background_tasks au démarrage.
Aligne aussi 4 tests MCP périmés de l'ancien protocole : idea_reply
retiré (erreur JSON-RPC -32601), idea_ask_agent exposé (13 tools),
rendez-vous capture le Final inline. cargo test -p app-tauri --lib
= 52 passed.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Câblage des événements de complétion/mailbox/réveil vers la couche
app-tauri pour consommation par le frontend (lots F1-F4 à venir).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
La conversation inter-agent (idea_ask_agent) doit rester strictement
headless : la cible répond via une session structured capturée par IdeA,
sans jamais écrire dans le PTY d'une cellule visible ni fermer le terminal
que l'utilisateur observe.
- lifecycle: flag `allow_structured_alongside_pty` — ouvre une session
structured pour la délégation sans fermer le PTY visible (coexistence).
- orchestrator/service: `ensure_structured_session` ne ferme plus le PTY
visible ; mapping typé de l'erreur no-reply ; coexistence PTY/structured.
- infrastructure/input: garantit zéro `DelegationReady` et zéro write PTY
pour une délégation headless, même quand l'entrée est `front_owned`.
- app-tauri (commands/state): câblage du flag de coexistence.
- tests: fixtures portées vers le modèle structured/headless, assertions
cibles mises à jour (aucun #[ignore] ajouté, aucun test retiré).
Validé réel : cargo build OK ; orchestrator_service 60/0, agent_lifecycle
62/0, structured_launch_d3 22/0, infrastructure input 35/0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
stale
Le backend renvoie l'id actif autoritaire et le
frontend l'adopte pour éviter de rejouer un layout
disparu après overwrite externe.
Co-Authored-By: Claude Opus 4.8
<noreply@anthropic.com>
Redessine la borne de fin de tour du rendez-vous `idea_ask_agent` ⇄ `idea_reply` :
au lieu d'un timeout plat (qui coupait à 600 s un seul long tour de la cible, cf.
T7), la borne devient une **fenêtre d'inactivité réarmée** à chaque progrès observé
de la cible, sous un **plafond absolu** (défaut 4 h, réglable via
`IDEA_ASK_RENDEZVOUS_CEILING_MS`).
- Sonde d'activité (`transcript_activity_token`, inspector) : jeton monotone =
octets cumulés des `.jsonl` de la cible. Croît même pendant un seul long tour
sans `turn_duration` ⇒ détecte « vivant et au travail » mi-tour. Best-effort,
sans effet de bord ; folder absent/illisible ⇒ « pas de progrès ».
- Watchdog (`run_inactivity_watchdog`, nouveau module `orchestrator/rendezvous`) :
fenêtre réarmable + plafond, fallback timeout plat si aucune sonde (zéro régression).
- Issue typée distincte `TargetCeilingActive` (code `RENDEZVOUS_CEILING_ACTIVE`) :
une cible **active** stoppée au plafond n'est jamais confondue avec un
`TargetReturnedNoReply` (silence) ; le message guide « ne pas retenter à l'aveugle ».
- Câblage composition-root (`state.rs`) : sonde résolue nom→AgentId→run-dir transcript,
branchée sur le service et sur l'McpServer (`AskActivityProbe`, `with_ask_ceiling`).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Au redémarrage, les agents qui étaient `working` lors de la fermeture restaient
figés en statut fantôme `working` alors qu'aucun tour n'est plus en cours (bug
reproductible en live : QA et DevBackend eux-mêmes sont restés `working` fantôme
après leurs tâches). On réconcilie l'état persistant à l'ouverture du projet :
les statuts orphelins sont ramenés à la cible `idle`.
- domain/live_state.rs : const STALE_AT_RESTART_MARKER + `reconcile_orphans` (+ tests).
- application/workstate/reconcile.rs (nouveau) : use case ReconcileLiveState (pas de
nouveau port), best-effort, no-op si store vide (+ tests, dont empty_store_is_a_noop_at_boot).
- application/workstate/mod.rs + lib.rs : module + re-export.
- app-tauri/state.rs : provider par-root + champ AppState + wiring.
- app-tauri/commands.rs : hook best-effort dans open_project.
QA VERT par commande réelle : cargo test --workspace 1624 passed / 0 failed,
cargo clippy --workspace --all-targets 0 erreur sur le code ajouté.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Remédiation du wedge persistant après échec live du fix Finding A (77e62e5).
Détecte la fin de tour d'un agent sollicité qui n'a pas appelé idea_reply et
débloque l'agent demandeur au lieu de le laisser en attente indéfinie.
Ajoute le suivi de tour côté inspector Claude (claude_turn_watcher) et la
résolution des chemins de session (claude_paths), câblés dans le rendez-vous
idea_ask_agent ⇄ idea_reply.
Build workspace vert, suite complète verte, zéro warning.
Backstop NON prouvé levé en live : merge develop interdit tant que la levée
du wedge n'est pas validée en conditions réelles.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Branche la mise à jour automatique du live-state sur le cycle de
délégation de l'orchestrateur, en best-effort non bloquant.
- Trait `LiveStateProvider` (résolution par root) + champ `Option` dans
l'`OrchestratorService`, injecté via le builder `with_live_state` ;
`None` ⇒ aucun effet (zéro régression).
- Transitions dérivées du cycle : `ask` → entrée `Working`,
`reply` → `Done` + `last_delegation`.
- Helpers best-effort : un échec de mise à jour du live-state ne
transforme jamais un succès de délégation en erreur.
- `AppLiveStateProvider` + wiring côté app-tauri (provider par root).
cargo test -p application : 0 échec ; --test orchestrator_service : 55/0
(dont 4 nouveaux tests LS3) ; cargo fmt --all --check : exit 0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
QA avait mis à jour le contrat 11→12 dans infrastructure/tests/mcp_server.rs
mais une seconde assertion codée en dur subsistait dans le test duplex de
state.rs. Ajoute idea_skill_read à la liste attendue et passe le compte à 12.
Conséquence directe de T4 (skill-awareness).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Surface les skills assignés à un agent « à la MCP » : description sur l'entité
Skill (+ effective_description fallback), section « # Skills disponibles » haute
altitude dans le convention-file (mode MCP), outil read-only idea_skill_read
(résolution projet→global), use case ReadSkill (port SkillStore existant), et
câblage au composition root. Dump legacy du corps complet conservé en mode
sans-MCP (zéro régression). Rétro-compat index.json (serde default).
Tests : domain+application+infrastructure 1212 passed / 0 failed (23 ajoutés).
Reste : T6 (champ description front) + T7 (e2e après rebuild AppImage).
NB topologie : commit réalisé par l'orchestrateur car l'agent Git était
injoignable (bug de livraison cold-start) ; à faire relire/rebaser par Git.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`unix_runtime_dir` essaie désormais les bases candidates dans l'ordre de
priorité ($XDG_RUNTIME_DIR → $TMPDIR → /tmp) et retient la première dont
le sous-dossier `idea-mcp` existe ou peut être créé. Un
$XDG_RUNTIME_DIR positionné mais inutilisable (sandbox/CI pointant un
chemin inexistant ou en lecture seule) ne doit plus dead-end le bind
loopback : sans ce fallback le socket ne se liait jamais en silence et la
délégation inter-agents mourait. Déterministe pour un environnement donné,
donc le côté bind et tout lecteur de `socket_path()` s'accordent sur le
même répertoire.
Indépendant du Lot E1.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
Ajoute un module d'actions contrôlées (`workstate/actions.rs`) côté application
et l'expose via des commandes Tauri : DTO camelCase, câblage commands/state/lib.
Les actions valident leurs invariants avant d'agir sur le read-model.
- application : use cases d'actions contrôlées + intégration au work-state.
- app-tauri : commandes dédiées, DTO et enregistrement dans le handler.
Tests verts : application workstate_actions (7), workstate (21),
app-tauri dto_agents (25), list_live_agents_r0b (5), cargo check OK.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Étend le read-model work-state pour exposer un résumé par conversation
(participants, dernier message/activité, compteurs) câblé jusqu'au DTO
camelCase de l'état app-tauri.
- application : assemblage des résumés de conversation dans le work-state.
- app-tauri : DTO camelCase des résumés + exposition dans l'état.
Tests verts : application workstate (21), app-tauri dto_agents (21),
aucun warning Rust.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ajoute un port de lecture ségrégué `AgentQueueSnapshot` (ISP) distinct du
`AgentMailbox` mutant : il expose `queue_for(agent)` qui renvoie des
`QueuedTicketSnapshot` clonés, ordonnés FIFO, avec position recalculée
(0 = tête). Observer la file ne la mute jamais ; le one-shot reply sender
reste dans l'adaptateur.
- domain : value object `QueuedTicketSnapshot` + trait `AgentQueueSnapshot`
(object-safe, partagé en `Arc<dyn …>`).
- infrastructure : `InMemoryMailbox` implémente la vue lecture en plus de la
vue mutation ; positions recalculées à chaque appel.
- application : le read-model work-state liste les délégations en attente via
ce port, troncature de l'aperçu de tâche en conservant la longueur d'origine.
- app-tauri : DTO `camelCase` des tickets en file câblé dans l'état.
Tests verts : domain mailbox (6), infrastructure mailbox (13),
application workstate (12), app-tauri dto_agents (20).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduit le module application `workstate` (modèle de read-model live + snapshots
des conversations/délégations en cours) et l'expose via la couche terminal
(exports mod/registry). Câble la surface Tauri : DTO, commande et state pour
exposer le live-state au frontend (lib + state + commands), avec tests.
QA verte. Réserve environnementale non bloquante : tests loopback socket Unix
réels non exécutables en sandbox (UnixListener::bind PermissionDenied),
alternatives avec skips vertes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Durcit le portail d'écriture de délégation et son acheminement bout-en-bout
(commande Tauri → orchestrateur → file d'entrée infrastructure → portail
frontend), avec une journalisation du submit pour diagnostiquer les cas où la
délégation n'était pas remise. Couvre le portail d'écriture côté front
(useWritePortal) avec ses tests.
QA : checks application/front/infrastructure/app-tauri verts. Les tests loopback
socket Unix réels ne sont pas exécutables en sandbox (UnixListener::bind →
PermissionDenied) ; alternatives avec skips vertes.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Introduit le modèle AgentManifest { version, entries, orchestrator } et la
garde d'écriture directe may_write_directly(..., &OrchestratorDesignation) :
seul l'orchestrateur désigné peut écrire directement, les autres passent par
le rendez-vous médié. Câble la désignation à travers domain → application →
infrastructure → app-tauri (context_guard, service, lifecycle, ports).
Ajoute crates/application/src/diag.rs : sink de diagnostic best-effort, sans
dépendance, qui miroite les traces du rendez-vous inter-agents de
l'orchestrateur vers un fichier de log persistant (utile au lancement via
AppImage où stderr est jeté), avec la même discipline « zéro dépendance,
ne casse jamais le rendez-vous ».
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>