Files
IdeA/.ideai/memory/ticket4-announcements-frontend-f1f2f3.md
Blomios f0adf2dcc4 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>
2026-07-04 19:50:22 +02:00

3.2 KiB

name, description, metadata
name description metadata
ticket4-announcements-frontend-f1f2f3 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.
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.