docs(memory): notes projet du redémarrage des annonces live (ticket #4)
Notes du chantier #4 relancé sur develop, commit séparé du code (convention d'usage) : - ticket4-restart-on-develop-ebd992e: baseline de redémarrage. - ticket4-overlay-composition-leafview: décision de composition de l'overlay dans le layout (LeafView). - ticket4-announcements-frontend-f1f2f3: cadrage de la surface frontend F1-F3. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
18
.ideai/memory/ticket4-announcements-frontend-f1f2f3.md
Normal file
18
.ideai/memory/ticket4-announcements-frontend-f1f2f3.md
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
name: ticket4-announcements-frontend-f1f2f3
|
||||
description: Topologie du frontend des annonces inter-agent (store borné, preview demandeur filtré requester, overlay cible piloté par le busy/idle par agent) — réintégré sur base develop.
|
||||
metadata:
|
||||
type: project
|
||||
---
|
||||
Branche `feature/agent-live-announcements` (base develop `ebd992e`, non commité). Frontend réintégré depuis `backup/announcements-work-20260704`. Feature `frontend/src/features/announcements/` :
|
||||
- `announcementsStore.ts` : index pur `byTarget[target][ticketId]->Announcement[]`, `appendAnnouncement` borné (cap 50), `purgeAllForTarget` (au busy:false), sélecteurs target/requester. Éphémère, jamais persisté. (`purgeTurn` du backup RETIRÉ — plus de signal final sur develop.)
|
||||
- `AnnouncementsProvider.tsx` (monté dans App.tsx) : 1 abonnement `system.onDomainEvent`. Deux signaux : CONTENU = `agentAnnouncement`→append ; CYCLE DE VIE = map `busy` par agent, seule autorité de montage/retrait, alimentée par `agentBusyChanged{agentId,busy}` + hydratée du read-model `ProjectWorkState.agents[].busy` via `useHydrateAgentBusy(projectId,agentId)` (seed « si absent » → event live gagne). `busy:false`→purgeAllForTarget. Hooks `useTargetAnnouncements` (active=busy[target]), `useRequesterAnnouncements`, `useHydrateAgentBusy`. Hors provider = store inerte.
|
||||
- F3 `TargetAnnouncementsOverlay(projectId,agentId)` monté dans **`LayoutGrid` LeafView** (PAS ConversationCell — absent sur develop ; la cellule agent est le PTY `TerminalView`). Overlay `pointer-events-none`, z-20, au-dessus du write-portal overlay existant. F2 `AnnouncementsPreview` par ligne d'`AgentsPanel` (requester==a.id).
|
||||
|
||||
ADAPTATION develop appliquée : `agentTurnEvent{final}` N'EXISTE PAS sur develop → branche de purge retirée du provider, type NON réintroduit dans domain, 2 tests agentTurnEvent supprimés. Autorité unique F3 = busy. Confirmé présents sur develop : `agentBusyChanged{agentId,busy}` (domain/index.ts) et `AgentWorkState.busy: {state:"idle"}|{state:"busy";ticket;sinceMs}`. DTO annonce backend confirmé (events.rs, test JSON à events.rs:927) : `{type:"agentAnnouncement",projectId,requester("user"|agentId),target,ticketId,text,atMs}` — mirroir ajouté dans domain/index.ts.
|
||||
|
||||
Exclusion des voiles (arbitrage [[ticket4-overlay-composition-leafview]]) : le voile write-portal (injection PTY) et l'overlay F3 partagent le conteneur relatif du LeafView. Prédicat pur exporté `shouldShowWritePortalVeil(agentPinned, writePortalOverlay, busyActive) = agentPinned && overlay && !busyActive` ; F3 se gate sur le même `busyActive` (`useTargetAnnouncements(agentId).active`, remonté au LeafView). Résultat : exactement UN voile, F3 prioritaire. Purement visuel — `portal.isSuspended()`/l'injection PTY (TerminalView) INCHANGÉS. Testé exhaustivement (table de vérité) dans `overlayExclusion.test.ts`.
|
||||
|
||||
Écarts tranchés à signaler : (1) F3 hébergé dans la cellule PTY (LeafView) faute de ConversationCell ; (2) busy est l'autorité brute : sur develop busy vient du mediator (délégations/inter-agent), pas du typing PTF humain, donc proxy correct, mais surveiller un éventuel over-trigger ; (3) F2 filtre requester seul (pas de ticketId par ligne) = garde anti-fuite.
|
||||
|
||||
Build vert, 51 fichiers / 481 tests vitest verts.
|
||||
25
.ideai/memory/ticket4-overlay-composition-leafview.md
Normal file
25
.ideai/memory/ticket4-overlay-composition-leafview.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
name: ticket4-overlay-composition-leafview
|
||||
description: Règle de composition des deux voiles plein-cellule de LeafView (write-portal injection PTY vs F3 annonces busy) — exclusion mutuelle avec priorité F3, arbitrée pour éviter le double voile.
|
||||
metadata:
|
||||
type: reference
|
||||
---
|
||||
Arbitrage layout Architect 2026-07-04 (branche feature/agent-live-announcements, base develop ebd992e, 481 tests verts).
|
||||
|
||||
**Problème vérifié :** LeafView héberge DEUX voiles plein-cellule inset:0 dans le même conteneur relatif :
|
||||
- write-portal (LayoutGrid.tsx:841, zIndex:4, rgba(0,0,0,0.45), « Un agent est en train de parler… ») = délégation injectée dans le PTY de l'agent (§20.3, flag `overlay` de useWritePortal).
|
||||
- F3 TargetAnnouncementsOverlay (z-20, bg-canvas/85, « …en train de LUI parler… » + réflexions) = agent busy (agentBusyChanged mediator).
|
||||
Ils rendent le MÊME événement depuis deux signaux et montent ENSEMBLE sur le chemin d'injection inter-agent (overlay+busy) → double voile empilé + bannières dupliquées = rendu cassé, chemin nominal.
|
||||
|
||||
**Décision (DevFrontend, layout, zéro backend) :** exclusion mutuelle, un seul voile à la fois, priorité F3 :
|
||||
- busy(agent) → F3 seul ; voile write-portal gated `agentId!=null && overlay && !busyActive`.
|
||||
- sinon overlay → write-portal seul (repli fenêtre sans busy).
|
||||
- jamais les deux.
|
||||
Sécurité : on ne touche que le visuel ; la suspension des frappes (portal.isSuspended(), TerminalView.tsx:182) reste ; F3 est pointer-events-none.
|
||||
|
||||
**Couplage point 3 :** F3 DOIT rendre la bannière sur busy même à 0 annonce (déjà: if(!active) return null, TargetAnnouncementsOverlay.tsx:56), car F3 absorbe le voile write-portal — une garde « ≥1 annonce » rouvrirait le trou d'indication. Pas de garde.
|
||||
|
||||
**F2 (point 4) :** filtre requester==id de ligne suffit en V1 (isolation fil partagé) ; ticketId optionnel dormant.
|
||||
**F3 hébergement (point 1) :** conteneur LeafView validé (pas de ConversationCell sur develop).
|
||||
|
||||
Liens : [[ticket4-restart-on-develop-ebd992e]], [[ticket4-f3-overlay-driven-by-agentbusychanged]], [[inter-agent-live-context-shared-per-agent]].
|
||||
20
.ideai/memory/ticket4-restart-on-develop-ebd992e.md
Normal file
20
.ideai/memory/ticket4-restart-on-develop-ebd992e.md
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
name: ticket4-restart-on-develop-ebd992e
|
||||
description: Cadrage du redémarrage des annonces inter-agent sur la base pré-canonique develop ebd992e — ce qui existe, l'écart live, la réutilisabilité du backup et le découpage B/F.
|
||||
metadata:
|
||||
type: reference
|
||||
---
|
||||
Redémarrage #4 sur base réalignée main=develop=feature/background=feature/agent-live-announcements=ebd992e (pré-canonique). Vérifié sur le dépôt le 2026-07-04.
|
||||
|
||||
**Signaux sur develop :**
|
||||
- Émission intermédiaire : AUCUNE. codex.rs draine via run_turn BATCH (process.rs:268/321 lit ligne-à-ligne mais collecte en Vec, renvoie à EOF ; codex.rs:260 Box::new(events.into_iter())). structured.rs:266-271 jette TextDelta/ToolActivity/Heartbeat, ne renvoie que Final.
|
||||
- Busy PAR AGENT : PRÉSENT ET COMPLET. DomainEvent::AgentBusyChanged{agent_id,busy} (domain/events.rs:171), autorité mediator (infrastructure/input/mod.rs:433), relay (app-tauri/events.rs:484), front event domain/index.ts:22 + read-model agents[].busy {state,ticket,sinceMs} (:220,304) réconcilié reboot. ⇒ autorité overlay F3 dispo telle quelle.
|
||||
- Fix Final : PRÉSENT (62915ee) mais dégrade les agent_message intermédiaires en ToolActivity{label} en JETANT leur texte, et reste batch → inexploitable pour annonces.
|
||||
|
||||
**Écart live (faisable SANS moteur canonique) :** run_turn lit déjà incrémentalement ; le batch n'est qu'un artefact de sa signature ->Vec. Ajouter un tap Option<mpsc::Sender<String>> dans run_turn/drain/drain_sandboxed (boucle existante) ; l'orchestrateur (qui détient requester/target/ticket) publie DomainEvent::AgentAnnouncement au fil de l'eau. Thread Landlock n'envoie que des lignes brutes ; publication bus hors thread. Pas de spawn_turn/AgentTurnEvent/ConversationId.
|
||||
|
||||
**Réutilisabilité backup (backup/announcements-work-20260704, 691b2ce) :** frontend features/announcements/ (store borné, provider, AnnouncementsPreview=F2, TargetAnnouncementsOverlay=F3) réutilisable ; F3 sur busy = intact sur develop. Dépend d'agentAnnouncement{requester,target,ticketId,text,atMs} (absent→B) et agentTurnEvent{final} (absent, secondaire → RETIRER du store). Backend backup non réutilisable (canonique) ; contrat/attribution repris.
|
||||
|
||||
**Découpage :** B1 domaine/appli (ReplyEvent::Announcement + DomainEvent::AgentAnnouncement + publish au drain) ; B2 infra = CŒUR (tap mpsc process.rs + codex émet Announcement{text} live) ; B3 relay/DTO ; F1 store (–hook final) ; F2 preview (filtre ticketId+requester==self) ; F3 overlay (réutilisé, busy seul autorité).
|
||||
|
||||
Liens : [[ticket4-f3-overlay-driven-by-agentbusychanged]], [[ticket4-announcements-reintegration-topology]], [[inter-agent-announcements-feature-and-codex-final-bug]], [[inter-agent-live-context-shared-per-agent]].
|
||||
Reference in New Issue
Block a user