chore(wip): état runtime .ideai (flux conversation live)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
File diff suppressed because one or more lines are too long
@ -72,3 +72,7 @@
|
||||
{"id":"7b0a1b7a-bfad-4d97-89f8-f4bb9b32740d","conversation":"d5068bc8-786e-0428-1d14-83b93961a15e","atMs":1781971869030,"source":{"kind":"agent","agentId":"a6ced819-b893-4213-b003-9e9dc79b9641"},"role":"prompt","text":"Implémente le Lot B backend/Tauri `workstate delegation/queue snapshot` sur la branche `feature/workstate-delegation-queue`. Respecte le cadrage Architect.\n\nObjectif:\n- Ajouter un port read-only `AgentQueueSnapshot` dans `domain/src/mailbox.rs` avec snapshots clonés des tickets, sans exposer ni cloner les senders.\n- Implémenter ce port pour `InMemoryMailbox` en conservant l'ordre FIFO et positions recalculées.\n- Étendre `GetProjectWorkState` pour inclure `agents[].tickets`, en croisant snapshot queue + `InputMediator::busy_state` pour dériver `inProgress` vs `queued`.\n- Conserver manifest boundary: tickets d'agents absents du manifeste ignorés.\n- Générer `taskPreview` côté application: trim, espaces normalisés, coupure ~160 caractères; conserver `taskLen` original utile.\n- Exposer DTO Tauri camelCase dans la commande existante `get_project_work_state`.\n\nDécision de périmètre: afficher les tickets `source == Agent` en priorité pour délégations; si tu inclus aussi human, explique et teste le libellé/source. Ne change pas la sémantique enqueue/resolve/cancel. Pas de nouvelle persistance, pas lecture log/handoff, pas événement queue changé.\n\nTests attendus:\n- infrastructure mailbox snapshot: ordre/metadata/read-only/update after resolve/cancel.\n- application workstate: queue vide, deux tickets ordonnés, busy first inProgress, idle queued, absent manifest ignored, preview truncation, source mapping.\n- app-tauri DTO serialization tickets.\n\nCommandes: `cargo fmt`, `cargo test -p infrastructure mailbox --lib`, `cargo test -p application --test workstate`, `cargo test -p app-tauri --test dto_agents`, `cargo check -p app-tauri`, et autres pertinentes. Ne committe pas. Ignore les fichiers runtime `.ideai/*` dirty, ne les modifie pas volontairement."}
|
||||
{"id":"2c25d734-281e-4f2a-850e-684fec6e0ba7","conversation":"d5068bc8-786e-0428-1d14-83b93961a15e","atMs":1781973784611,"source":{"kind":"agent","agentId":"a6ced819-b893-4213-b003-9e9dc79b9641"},"role":"prompt","text":"Reprise orchestration Main. Je retrouve la branche `feature/workstate-delegation-queue` avec des modifications backend/Tauri non committées pour le Lot B `workstate delegation/queue snapshot` (ticket mentionné par l'utilisateur: dbca904a-2843-4f41-9926-d13b7804c70f). Peux-tu confirmer ton état exact: périmètre implémenté, choix notables (notamment tickets human inclus ou exclus), commandes exécutées et résultats réels, et ce qu'il reste selon toi ? Ne modifie rien, ne committe pas."}
|
||||
{"id":"b0d07b39-565c-4d30-a9ae-0c3721338aeb","conversation":"d5068bc8-786e-0428-1d14-83b93961a15e","atMs":1781973900817,"source":{"kind":"agent","agentId":"73c853d1-c0fd-463b-ad17-1d24fefa371f"},"role":"response","text":"État DevBackend — branche `feature/workstate-delegation-queue`, Lot B « workstate delegation/queue snapshot » (ticket dbca904a). **Rien committé, rien modifié pendant ce diagnostic.**\n\n## Périmètre implémenté\nExtension du read-model live-state (Lot A) pour exposer, **par agent**, ses tickets de délégation en file FIFO. 4 couches touchées (sens hexagonal respecté) :\n\n- **domain/mailbox.rs** : nouveau value object `QueuedTicketSnapshot` (données du ticket + `position`, 0 = tête ; **jamais** le `oneshot::Sender`) + nouveau **port lecture seule** `AgentQueueSnapshot` (`queue_for(agent) -> Vec<QueuedTicketSnapshot>`), **ségrégé (ISP)** du port mutant `AgentMailbox`. Re-export depuis `domain/lib.rs`.\n- **infrastructure/mailbox/mod.rs** : `impl AgentQueueSnapshot for InMemoryMailbox` — clone les données sous le lock, recalcule la position depuis l'ordre courant, lecture pure (n'altère pas la file).\n- **application/workstate/mod.rs** : nouveaux `AgentTicketState`, `TicketWorkStatus` (InProgress/Queued), `TicketWorkSource` (Human/Agent), `task_preview` (160 car., espaces normalisés) + `task_len`. `GetProjectWorkState` gagne une dépendance `queue: Arc<dyn AgentQueueSnapshot>` ; champ `AgentWorkState.tickets` peuplé.\n- **app-tauri/dto.rs** : `AgentTicketStateDto`, `TicketWorkStatusDto`, `TicketWorkSourceDto` (camelCase, enum source taggée `kind`), champ `AgentWorkStateDto.tickets`.\n- **app-tauri/state.rs** : composition root — même `InMemoryMailbox` concret partagé en **deux vues Arc** (`AgentMailbox` mutant + `AgentQueueSnapshot` lecture), injecté dans `GetProjectWorkState`.\n\n## Choix notables\n- **Tickets human INCLUS** (pas de filtrage par source). `TicketWorkSource::Human`/`Agent{agent_id}` mappé dans les deux sens, couvert par le test `workstate_maps_human_and_agent_ticket_sources`. La file liste tous les tickets quelle que soit l'origine.\n- **Statut dérivé, jamais stocké** : InProgress = ticket dont l'id == ticket busy courant de l'agent ; les autres Queued ; agent idle → tout Queued.\n- **ISP** : port lecture distinct plutôt que d'élargir `AgentMailbox` ; observer la file ne la mute jamais (test dédié).\n- **task_preview borné** à 160 car., texte intégral jamais envoyé à l'UI, longueur réelle via `task_len`.\n- **Frontière manifest préservée** : seuls les agents du manifest reçoivent des tickets ; file d'un agent absent du manifest ignorée (test dédié).\n\n## Commandes exécutées (à l'instant) + résultats réels\n`cargo test -p domain -p application -p infrastructure -p app-tauri` → **tout vert, 0 échec**.\n- domain : 176 unit (+1 nouveau `queued_ticket_snapshot_…`)\n- infrastructure : 228 unit (+6 nouveaux `snapshot_*` : empty/fifo-order/metadata/read-only/après resolve/après cancel)\n- application : 43 unit + `workstate.rs` **12** (+7 nouveaux : sans-queue, fifo, busy→in-progress, idle→tout-queued, agent-hors-manifest, troncature preview, sources human+agent)\n- app-tauri : lib 47 + `dto_agents.rs` (+1 `project_work_state_dto_serialises_tickets_camelcase`)\nAucun warning bloquant.\n\n## Ce qu'il reste (selon moi)\n1. **Frontend (périmètre DevFrontend)** : aucune consommation TS/React des nouveaux champs DTO `tickets` — rendu du panneau de délégations non fait.\n2. **Commit/merge (périmètre Git)** : 14 fichiers non commités ; le code backend est prêt à committer. À noter : les fichiers `.ideai/` modifiés (conversations/handoff/log/layouts) sont du **bruit runtime**, pas la feature.\n3. **Validation e2e/AppImage** : non faite (binaire qui tourne = AppImage, pas les sources).\n4. **Cadrage Architect** : si tu veux une validation formelle du nouveau port `AgentQueueSnapshot` dans `architect.md`, je l'ai conçu en cohérence ISP mais ce n'est pas tranché dans la cartographie.\n\nEn résumé : backend Lot B **complet et vert** au niveau tests unitaires/intégration ; restent le front, le commit Git et la validation e2e."}
|
||||
{"id":"c12097a1-1a74-4326-be18-c28424c43947","conversation":"d5068bc8-786e-0428-1d14-83b93961a15e","atMs":1781975317853,"source":{"kind":"agent","agentId":"a6ced819-b893-4213-b003-9e9dc79b9641"},"role":"prompt","text":"Implémente le Lot C backend/Tauri `workstate conversation summaries` sur la branche active `feature/workstate-conversation-summaries`. Respecte strictement le cadrage Architect ci-dessous.\n\nObjectif produit:\n- Enrichir `ProjectWorkState` avec `conversations: Vec<ConversationWorkSummary>` top-level, jointes côté frontend via `tickets[].conversationId`.\n- Résumer uniquement les conversations visibles via les tickets du work-state (conversation ids présents dans `AgentTicketState`).\n- Read-only, best-effort: aucune nouvelle persistance, aucune mutation/réparation de log/handoff, aucun blocage du live/busy/tickets si preview KO.\n\nSources:\n- Primaire: `HandoffStore` (`.ideai/conversations/<id>/handoff.md`).\n- Fallback: `ConversationLog::last(conversation, 3)` uniquement, jamais lecture complète.\n- `ConversationRegistry` n'est pas source de vérité pour ce lot.\n\nModèle application recommandé:\n- `ProjectWorkState { agents: Vec<AgentWorkState>, conversations: Vec<ConversationWorkSummary> }`.\n- `ConversationWorkSummary { conversation_id, status, objective_preview, summary_preview, summary_len, up_to, recent_turns }`.\n- `ConversationPreviewStatus`: `Ready | Missing | Partial | Unavailable`.\n- `ConversationTurnWorkPreview { role, source, at_ms, text_preview, text_len }`.\n\nBornes:\n- `HANDOFF_PREVIEW_MAX_CHARS = 480`\n- `OBJECTIVE_PREVIEW_MAX_CHARS = 160`\n- `RECENT_TURNS_MAX = 3`\n- `TURN_PREVIEW_MAX_CHARS = 220`\n- Normalisation: trim + collapse whitespace + truncation char-safe.\n\nAlgorithme:\n1. Dédupliquer les `conversation_id` issus des tickets projetés.\n2. Tenter `handoffs.load(conversation)`.\n3. Si handoff présent et utilisable: `status = Ready`, `summaryPreview`, `summaryLen`, `objectivePreview`, `upTo`.\n4. Si absent: `status = Missing`, tenter `log.last(conversation, 3)` et remplir `recentTurns` si possible.\n5. Si handoff illisible/erreur mais log lisible: `status = Partial`, `summaryPreview = None`, `recentTurns`.\n6. Si handoff et log échouent: `status = Unavailable`, champs preview vides.\n7. Ne jamais transformer une erreur preview en `AppError` global.\n\nDTO Tauri:\n- Garder `get_project_work_state`.\n- Ajouter `ProjectWorkStateDto.conversations` camelCase.\n- Statuts en `ready/missing/partial/unavailable`.\n- Types TS seront faits par DevFrontend ensuite, mais les DTO Rust doivent être clairs.\n\nTests attendus:\n- `crates/application/tests/workstate.rs`: agents/live/busy/tickets conservés si preview échoue; conversation ids dédupliqués; handoff présent ready; handoff absent + log présent missing avec recentTurns borné; handoff erreur + log lisible partial; handoff/log KO unavailable; previews tronquées et whitespace normalisé.\n- `crates/app-tauri/tests/dto_agents.rs`: sérialisation camelCase `conversations`, statuts, `recentTurns`.\n- Infrastructure seulement si nécessaire; ne crée pas d'adapter inutile.\n\nCommandes minimales:\n- `cargo fmt --all -- --check`\n- `cargo test -p application --test workstate`\n- `cargo test -p app-tauri --test dto_agents`\n- `cargo check -p app-tauri`\n- autres pertinentes si tu touches infra/domain.\n\nContraintes:\n- Ne committe pas.\n- Ignore dirty runtime éventuel `.ideai/*`.\n- Retourne fichiers modifiés, signatures/types ajoutés, choix exacts si divergence, commandes exécutées et résultats réels."}
|
||||
{"id":"b9900b46-41ff-4276-a225-991520cf0923","conversation":"d5068bc8-786e-0428-1d14-83b93961a15e","atMs":1781976051405,"source":{"kind":"agent","agentId":"73c853d1-c0fd-463b-ad17-1d24fefa371f"},"role":"response","text":"Lot C backend/Tauri `workstate conversation summaries` **implémenté et vert** sur `feature/workstate-conversation-summaries`. **Rien commité.**\n\n## Fichiers modifiés (6 ; aucun infra/domain — ports HandoffStore/ConversationLog réutilisés)\n- `crates/application/src/workstate/mod.rs` — modèle + algo best-effort\n- `crates/application/src/lib.rs` — re-exports\n- `crates/app-tauri/src/dto.rs` — DTO camelCase\n- `crates/app-tauri/src/state.rs` — wiring composition root\n- `crates/application/tests/workstate.rs` — fakes + 9 tests\n- `crates/app-tauri/tests/dto_agents.rs` — +1 test + 2 littéraux existants mis à jour\n\n## Signatures/types ajoutés\n**Application :**\n- `ProjectWorkState.conversations: Vec<ConversationWorkSummary>` (top-level)\n- `ConversationWorkSummary { conversation_id, status, objective_preview: Option<String>, summary_preview: Option<String>, summary_len: usize, up_to: Option<TurnId>, recent_turns: Vec<ConversationTurnWorkPreview> }`\n- `enum ConversationPreviewStatus { Ready, Missing, Partial, Unavailable }`\n- `ConversationTurnWorkPreview { role: TurnRole, source: TicketWorkSource, at_ms: u64, text_preview: String, text_len: usize }`\n- `trait ConversationLogProvider { fn conversation_log_for(&self, root: &ProjectPath) -> Option<Arc<dyn ConversationLog>> }` (nouveau, jumeau de `HandoffProvider`)\n- `GetProjectWorkState::with_conversation_sources(handoffs: Arc<dyn HandoffProvider>, logs: Arc<dyn ConversationLogProvider>)` (builder)\n- Constantes : `HANDOFF_PREVIEW_MAX_CHARS=480`, `OBJECTIVE_PREVIEW_MAX_CHARS=160`, `RECENT_TURNS_MAX=3`, `TURN_PREVIEW_MAX_CHARS=220`\n\n**DTO Tauri :** `ProjectWorkStateDto.conversations`, `ConversationWorkSummaryDto`, `ConversationPreviewStatusDto` (`ready/missing/partial/unavailable`), `ConversationTurnWorkPreviewDto`. **state.rs :** `AppConversationLogProvider` (matérialise `FsConversationLog::new(root)`), câblé via `.with_conversation_sources(AppHandoffProvider, AppConversationLogProvider)`.\n\n## Choix exacts / divergences\n1. **Réutilisé `HandoffProvider` existant (P7)** comme source primaire + ajouté le jumeau `ConversationLogProvider` pour le repli. Résolus **par project root** (`input.project.root`) car `GetProjectWorkState` est singleton AppState alors que les `Fs*` figent leur racine à la construction — strictement parallèle au pattern P7/P8b.\n2. **Builder `with_conversation_sources`** plutôt que d'étendre `new(...)` : sources OFF par défaut, zéro régression sur call sites/tests existants (best-effort absent = aucune summary).\n3. **« provider non câblé » = handoff Absent (chemin Missing), jamais une erreur.** `Unavailable` strictement = handoff **erreur** ET log erreur/absent. `Missing` reste Missing même si le log échoue (alors recentTurns vide). Conforme aux étapes 4/5/6 du cadrage.\n4. **Ready** ne remplit pas `recent_turns` (le handoff EST le résumé) ; recentTurns peuplé seulement en Missing/Partial. Re-cap défensif à `RECENT_TURNS_MAX` en plus de `log.last(_, 3)`.\n5. **Dédup** des `conversation_id` sur tous les tickets projetés (humains inclus), **ordre first-seen** pour refléter l'ordre du panneau.\n6. **`TurnRole` domaine réutilisé tel quel dans le DTO** (sérialise déjà camelCase `prompt/response/toolActivity`), cohérent avec le réemploi de `AgentBusyState` ; `source` du tour réutilise `TicketWorkSourceDto` (`kind: human/agent`).\n7. **Champs preview optionnels sérialisés en `null`** quand absents (pas omis) — prévisible pour le front, aligné sur le pattern `live` (divergence assumée vs `ConversationDetailsDto` qui omet).\n8. **Normalisation factorisée** : helper `preview(text, max)` partagé (trim + collapse whitespace + troncature char-safe), `task_preview` (Lot B) refactoré dessus.\n\n## Commandes exécutées + résultats réels\n- `cargo fmt --all -- --check` → **clean** (après `cargo fmt --all`).\n- `cargo test -p application --test workstate` → **21 passed; 0 failed** (12 existants + 9 nouveaux : has_no_conversations, dedups, ready, missing+bounded(3), partial, unavailable, preview_failure_preserves_agents/live/busy/tickets, previews_truncated+normalised, turn_text_truncated).\n- `cargo test -p app-tauri --test dto_agents` → **21 passed; 0 failed** (+1 `project_work_state_dto_serialises_conversations_camelcase`).\n- `cargo check -p app-tauri` → **clean** (domain/application/infrastructure/app-tauri compilent).\n\nPas d'adapter infra créé (réemploi de `FsHandoffStore`/`FsConversationLog` existants). Dirty runtime `.ideai/*` ignoré. Reste : types TS (DevFrontend) + commit/merge (Git) + validation e2e."}
|
||||
{"id":"0834676a-dc01-4cdf-97a4-37cff81bf3d2","conversation":"d5068bc8-786e-0428-1d14-83b93961a15e","atMs":1781976363926,"source":{"kind":"agent","agentId":"a6ced819-b893-4213-b003-9e9dc79b9641"},"role":"prompt","text":"QA Lot C est verte mais signale un warning Rust non bloquant: `variant Absent is never constructed` dans `crates/application/tests/workstate.rs:173:5`, probablement un enum/fake de test `HandoffOutcome::Absent` inutilisé.\n\nMerci de nettoyer ce warning de façon minimale sans changer le comportement applicatif, puis relance au moins:\n- `cargo fmt --all -- --check`\n- `cargo test -p application --test workstate`\n\nNe committe pas. Retourne le diff conceptuel, les fichiers modifiés, et les résultats réels."}
|
||||
{"id":"8e30c171-2d32-48ab-9971-c6d23a010052","conversation":"d5068bc8-786e-0428-1d14-83b93961a15e","atMs":1781976412762,"source":{"kind":"agent","agentId":"73c853d1-c0fd-463b-ad17-1d24fefa371f"},"role":"response","text":"Warning nettoyé. **Rien commité.**\n\n## Diff conceptuel\nLa variante `HandoffOutcome::Absent` du fake de test n'était jamais construite : l'absence de handoff était déjà modélisée en **ne configurant pas** la conversation (le `load` du fake retombait sur l'arm `_ => Ok(None)`). Correctif minimal, zéro impact applicatif (uniquement le fixture de test) :\n- Suppression de la variante `Absent` (+ doc-comment expliquant que l'absence = conversation non configurée).\n- Le match de `FakeHandoffStore::load` passe de `_ => Ok(None)` à `None => Ok(None)` (désormais exhaustif sur `Present`/`Error`/`None`, plus de wildcard).\nAucun test ne référençait `Absent` (le test `missing` repose sur une conversation non configurée), donc aucune logique de test ni d'assertion modifiée.\n\n## Fichier modifié\n- `crates/application/tests/workstate.rs` (uniquement)\n\n## Résultats réels\n- `cargo fmt --all -- --check` → **clean** (exit 0).\n- `cargo test -p application --test workstate` → **21 passed; 0 failed**, **aucun warning** (le `variant Absent is never constructed` a disparu)."}
|
||||
|
||||
Reference in New Issue
Block a user