Templates (v7.71.x) : - registre unifié \ emplates\ (migrations 48-49) + TemplateService.instantiate unique (UI, API v2, agent, scheduler) - sélecteur (pilule page vide, menu •••, commande /template), gestionnaire /templates, menu New ▾, From template, base inline dans un document - 141 presets système (59 pages, 42 bases, 15 blocs, 25 lignes), titre auto depuis le template, variables title réservée - récurrences RRULE + scheduler dédupliqué, agent apply_template/list_templates, API /api/templates + /api/v2/fd-templates - correctifs : bouton Templates, centrage fenêtre, filtres CSP, flux de création, variable title - tests : tests/test_fd_templates.py (19) et e2e/templates_picker.spec.js (8) Inclut le travail déjà présent dans le working tree (vues Notion : view_query/view_aggregate/form_projection/geocoding, property_types, database_table, docs agents-skills) et ignore .playwright-mcp/.
305 lines
27 KiB
Markdown
305 lines
27 KiB
Markdown
# Agents & Skills pour Flowdeck — Phase 4 : Agir dehors, travailler sur fichiers, compter
|
||
|
||
| Champ | Valeur |
|
||
|---|---|
|
||
| Phase | **4 sur 5** — la parité complète (dernière phase de fonctionnalité) |
|
||
| Document parent | `architecture-agents-skills-notion-flowdeck.md` v1.1 — en particulier §3.2 et §3.5–3.6, §10.6–10.7, §14, §15, §16.3–16.5 |
|
||
| Version | 1.0 — 9 octobre 2026 |
|
||
| Auteur | Spark, pour Bruno |
|
||
| Statut | Prêt à implémenter **après la Phase 3** |
|
||
| Prérequis | Phase 3 (dispatcher, régime `allowlist`, approbations en autonome) |
|
||
| Migrations créées | **42** (modèles & usage) et **43** (fichiers des runs) |
|
||
| Débloque | Phase 5 (optimisations sur données réelles d'usage et de coûts) |
|
||
|
||
> **Résultat visible à la fin de cette phase.** L'Agent agit dans le monde extérieur, sous confirmation : il cherche et poste dans **Slack** (nouveau connecteur), rédige/envoie/archive dans **Gmail**, **trouve un créneau** entre participants avec des suggestions classées et une grille, puis réserve ; il **gère l'Inbox** Flowdeck par le chat ; les Custom Agents gagnent des déclencheurs messagerie/courriel/calendrier. Dans le chat, on **dépose des fichiers** (PDF, CSV, XLSX, DOCX, PPTX, ZIP) que l'Agent lit, analyse avec du code sandboxé, transforme en pages ou bases, et il **rend des fichiers téléchargeables**. Et tout est **compté** : modèles autorisés par surface, modèles premium activés par l'admin, allocation d'usage, crédits, limites par membre et par agent, tableaux d'usage.
|
||
|
||
---
|
||
|
||
## Table des matières
|
||
|
||
1. [Objectif](#1-objectif)
|
||
2. [Périmètre](#2-périmètre)
|
||
3. [État d'entrée](#3-état-dentrée)
|
||
4. [Modèle de données — migrations 42 et 43](#4-modèle-de-données--migrations-42-et-43)
|
||
5. [Tickets de travail](#5-tickets-de-travail)
|
||
6. [API livrée par la phase](#6-api-livrée-par-la-phase)
|
||
7. [Comportements détaillés](#7-comportements-détaillés)
|
||
8. [Tests](#8-tests)
|
||
9. [Critères d'acceptation](#9-critères-dacceptation)
|
||
10. [Risques spécifiques et vigilance](#10-risques-spécifiques-et-vigilance)
|
||
11. [Ordre d'exécution](#11-ordre-dexécution)
|
||
12. [Définition de « terminé »](#12-définition-de--terminé-)
|
||
|
||
---
|
||
|
||
## 1. Objectif
|
||
|
||
Trois chantiers indépendants mais livrés ensemble parce qu'ils partagent la même exigence — **ne jamais agir ou dépenser dans l'ombre** :
|
||
|
||
1. **Les actions externes** (écarts E8 du parent) : chaque écriture hors Flowdeck est un outil de classe `EXTERNAL_WRITE`, confirmé ou couvert par une politique explicite, et journalisé comme les écritures internes.
|
||
2. **L'espace fichiers** (écart E9 + E10) : l'Agent cesse d'être limité au texte du workspace ; il ingère, calcule et produit, en assemblant importers, sandbox Workers et exports existants.
|
||
3. **La comptabilité** (écart E13) : les modèles deviennent gouvernés (autorisés par surface, premium activés) et chaque run a un coût calculé depuis un journal — c'est ce qui rend les deux premiers chantiers soutenables en production.
|
||
|
||
## 2. Périmètre
|
||
|
||
### 2.1 Inclus
|
||
|
||
- Contrat « agent-ready » pour les connecteurs (sources / outils de lecture / outils d'écriture / déclencheurs / identité) appliqué à tous les connecteurs livrés dans la phase.
|
||
- Connecteur **Slack** natif : connexion workspace (admin) + connexion de compte (utilisateur) ; outils de l'Agent personnel (identité *utilisateur*) et des Custom Agents (canaux accordés) ; déclencheurs message/réaction/mention.
|
||
- Google/MS365 : second consentement pour les **scopes d'écriture** ; outils Gmail (brouillon, envoi, archive, étiquettes, corbeille, désabonnement) ; outils calendrier (trouver un créneau + grille, créer, préparer, déplacer si organisateur) ; dépôt d'un fichier produit dans Drive/Files.
|
||
- Outils **Inbox** : lire/résumer, regrouper, marquer, archiver (dont en masse avec confirmation et compte exact) ; bornes documentées (pas de décision d'approbation, pas de création de notification, pas de réglages).
|
||
- Promotion des connecteurs Discord/Telegram/Teams au contrat agent-ready (canaux comme sources, cibles d'envoi, déclencheurs).
|
||
- Déclencheurs Phase 4 dans le dispatcher de la Phase 3 : `message.posted`, `message.reaction`, `message.mention` (par connecteur), `mail.received`, `calendar.event_created/updated/cancelled`.
|
||
- Classe d'outils `EXTERNAL_WRITE` dans la gouvernance : approbation par défaut, politiques pré-approuvées bornées (outil × cible) pour les Custom Agents, envoi de courriel toujours confirmé pour l'Agent personnel.
|
||
- Espace fichiers : dépôt dans le chat (trombone + glisser-déposer), `agent_run_files`, extraction par les importers, profil tabulaire, outil `run_code_on_data` sur la sandbox Workers avec montage borné, `produce_file` (XLSX, PDF, DOCX, PPTX), `create_collection_from_file`, **tableau interactif de résultats** dans le chat, rétention et purge.
|
||
- Migration 42 : `workspace_ai_settings` (modèles autorisés par surface, premium, modèle par défaut, limites, qui peut créer des agents, accès web par défaut), `ai_usage_ledger` ; service `usage_meter` ; tarification par modèle en réglages ; allocation d'usage (fenêtre calculée depuis le journal) ; limites membre et agent appliquées au routage de modèle ; tableaux d'usage (admin) et coût par run dans Activity ; webhooks de seuil de crédits.
|
||
- Application de `credit_limit_monthly` (Phase 3, colonne créée) et de `who_can_create_agents`.
|
||
|
||
### 2.2 Exclu
|
||
|
||
- Le **serveur MCP** Flowdeck (chantier séparé déjà documenté côté Flowdeck) et le SDK d'agents externe → Phase 5 (préparation seulement).
|
||
- Les connecteurs métier nouveaux au-delà de Slack (CRM, billetterie…) : le contrat agent-ready et le client MCP les couvrent sans code dédié.
|
||
- La refacturation réelle : les crédits sont une unité de compte interne (question ouverte Q1 du parent : quotas de gouvernance ou reflet de coûts fournisseurs — le journal livré ici sert les deux, seuls les taux changent).
|
||
|
||
## 3. État d'entrée
|
||
|
||
| Élément | État |
|
||
|---|---|
|
||
| Connecteurs natifs (gitea, github, web, google, ms365) + personnels (custom, discord, telegram, mcp) ; OAuth Google/MS365 **lecture seule**, refresh auto, secrets Fernet | Existants (§16.4 de l'architecture) |
|
||
| `connectors.py` (fetch gardé SSRF), `oauth_connectors.py`, client MCP complet | Existants |
|
||
| Importers (PDF, DOCX, CSV/XLSX, ZIP via pipeline) ; exports (XLSX, PDF, DOCX…) | Existants (§21) |
|
||
| Workers sandboxés (AST, pas de réseau/filesystem, timeout 30 s, budget journalier) | Existants (§19.2) |
|
||
| Service de notifications + Inbox sidebar | Existant (§19.4) |
|
||
| `agent_approvals`, webhooks `agent.*`, dispatcher + régime `allowlist`, `agent_runs` avec `credits` à 0 | Livrés Phases 2–3 |
|
||
| `llm_config` (23 fournisseurs, précédence 4 niveaux) | Existant — les taux par modèle s'y ajoutent |
|
||
|
||
## 4. Modèle de données — migrations 42 et 43
|
||
|
||
```sql
|
||
-- Migration 42 — Phase 4 (gouvernance modèles & usage)
|
||
CREATE TABLE workspace_ai_settings (
|
||
workspace_id INTEGER PRIMARY KEY REFERENCES workspaces(id),
|
||
allowed_models_personal_json TEXT DEFAULT '[]', -- [] = tous les modèles configurés
|
||
allowed_models_custom_json TEXT DEFAULT '[]',
|
||
premium_models_json TEXT DEFAULT '[]', -- activés par l'admin
|
||
default_model TEXT,
|
||
member_credit_limit INTEGER, -- crédits / membre / mois ; NULL = illimité
|
||
allowance_json TEXT DEFAULT '{}', -- {window_hours, volume} de l'allocation incluse
|
||
who_can_create_agents TEXT DEFAULT 'everyone', -- 'everyone' | 'admins'
|
||
web_access_default INTEGER NOT NULL DEFAULT 0,
|
||
updated_by INTEGER REFERENCES users(id), updated_at TEXT
|
||
);
|
||
CREATE TABLE ai_usage_ledger (
|
||
id INTEGER PRIMARY KEY,
|
||
workspace_id INTEGER NOT NULL,
|
||
run_id INTEGER REFERENCES agent_runs(id),
|
||
user_id INTEGER REFERENCES users(id),
|
||
agent_id INTEGER REFERENCES agents(id),
|
||
provider TEXT, model TEXT,
|
||
tokens_in INTEGER DEFAULT 0, tokens_out INTEGER DEFAULT 0,
|
||
credits REAL NOT NULL DEFAULT 0,
|
||
bucket TEXT NOT NULL DEFAULT 'allowance', -- 'allowance' | 'premium'
|
||
created_at TEXT NOT NULL
|
||
);
|
||
-- Index : (workspace_id, created_at), (user_id, created_at), (agent_id, created_at).
|
||
-- Taux par modèle : table de correspondance dans les réglages (JSON versionné),
|
||
-- {"<provider>/<model>": {"in_per_1k": x, "out_per_1k": y, "premium": bool}}
|
||
-- le mode offline a un taux de 0 par construction.
|
||
|
||
-- Migration 43 — Phase 4 (espace fichiers)
|
||
CREATE TABLE agent_run_files (
|
||
id INTEGER PRIMARY KEY,
|
||
run_id INTEGER REFERENCES agent_runs(id),
|
||
conversation_id INTEGER REFERENCES agent_conversations(id),
|
||
direction TEXT NOT NULL, -- 'input' | 'output'
|
||
name TEXT NOT NULL, mime TEXT, size INTEGER,
|
||
storage_path TEXT NOT NULL, -- data/uploads/agent-files/<conversation_id>/…
|
||
created_at TEXT NOT NULL,
|
||
expires_at TEXT -- NULL = livrable conservé par l'utilisateur
|
||
);
|
||
```
|
||
|
||
Règles : le ledger est **append-only** (aucune correction d'écriture — un ajustement est une ligne négative motivée, créée par un admin) ; les agrégats (allocation consommée, crédits du mois) sont **toujours calculés** depuis le ledger ; `agent_run_files` ne stocke jamais le contenu en base.
|
||
|
||
## 5. Tickets de travail
|
||
|
||
### Le contrat connecteur et Slack
|
||
|
||
**P4-T01 — Contrat agent-ready et registre des capacités.**
|
||
Fichiers : `app/services/connectors.py` (extension), registre dans `tool_registry.py`.
|
||
Travail : formaliser la déclaration de capacités du parent §14.1 (sources, read_tools, write_tools, triggers, identité) ; le sélecteur *All sources* (Phase 2) et le Tool Registry consomment cette déclaration au lieu de listes codées en dur ; un connecteur sans déclaration reste utilisable en lecture comme aujourd'hui (compatibilité).
|
||
Acceptation : brancher un connecteur de test déclaratif suffit à le faire apparaître dans All sources et dans les outils, sans autre code.
|
||
|
||
**P4-T02 — Connecteur Slack natif : connexions.**
|
||
Fichiers : catalogue des connecteurs natifs, flux OAuth (patron des natifs existants).
|
||
Travail : connexion **workspace** par un admin (préalable aux agents) stockée comme les autres connecteurs workspace ; connexion **compte** par utilisateur pour l'Agent personnel (jeton utilisateur, Fernet) ; écran de statut distinguant les deux niveaux ; révocation indépendante.
|
||
Acceptation : sans connexion workspace, les déclencheurs Slack d'agents sont refusés proprement ; sans connexion compte, l'Agent personnel signale le manque au lieu d'échouer en cours de run.
|
||
|
||
**P4-T03 — Outils Slack.**
|
||
Travail : lecture (chercher des personnes ; lire canaux publics/privés et fils **dans la visibilité du jeton utilisé** ; lire les fichiers partagés récents) et écritures `EXTERNAL_WRITE` (poster, répondre en fil, éditer **ses propres** messages, réagir) ; identité *utilisateur* pour l'Agent personnel (les messages portent son nom), identité *agent* pour les Custom Agents limitée aux canaux présents dans `agent_access` (extension de `resource_type` à `'channel'`) ; l'outil d'édition refuse tout message non émis par la même identité.
|
||
Acceptation : test de borne — avec un jeton limité à un canal, aucune lecture ni écriture hors de ce canal n'est possible, y compris par recherche.
|
||
|
||
**P4-T04 — Déclencheurs Slack et messageries existantes.**
|
||
Travail : émission vers le bus — Slack : `message.posted` (filtres mots-clés, inclusion des fils), `message.reaction`, `message.mention` ; indicateur d'activité dans le canal pendant le run (`show_typing` du déclencheur) ; promotion de Discord/Telegram/Teams au même contrat : leurs événements existants alimentent les mêmes `event_name`, leurs canaux deviennent des ressources accordables et des cibles de `channel_post`.
|
||
Acceptation : UC-05 (rapport horaire posté) et un triage sur mention fonctionnent sur Slack **et** sur un connecteur de messagerie préexistant, sans code de dispatcher différent.
|
||
|
||
### Écritures Google / Microsoft 365 et Inbox
|
||
|
||
**P4-T05 — Second consentement d'écriture et outils Gmail.**
|
||
Fichiers : `app/services/oauth_connectors.py`.
|
||
Travail : demande de scopes d'écriture séparée et révocable indépendamment (l'état « lecture seule » reste le défaut et un état stable) ; outils : `mail_draft`, `mail_send`, `mail_archive`, `mail_label`, `mail_trash` (+ désabonnement d'expéditeur) sur Gmail et, en parité de contrat, Outlook/Graph ; l'envoi est **toujours** confirmé pour l'Agent personnel (carte d'approbation montrant destinataires, objet, corps complet) ; pour les Custom Agents, l'envoi exige une politique pré-approuvée explicite par boîte.
|
||
Acceptation : aucun envoi ne part sans que le contenu exact envoyé soit celui qui a été approuvé (hash du contenu dans la demande d'approbation, revérifié à l'exécution).
|
||
|
||
**P4-T06 — Outils calendrier d'agent.**
|
||
Travail : `calendar_find_time` (croise les disponibilités des participants sur les calendriers connectés, rend des suggestions **classées** avec les motifs du classement — chevauchements évités, préférences horaires — et la matière de la **grille interactive** rendue dans le panneau : créneaux × participants, sélection en un clic) ; `calendar_create_event` (organisateur = l'utilisateur ou l'agenda accordé) ; `calendar_prep` (assemble événement, participants, pages liées, dernière note de réunion) ; `calendar_move/cancel` bornés aux événements dont l'acteur est organisateur ; en multi-calendriers : calendrier par défaut, sinon question à l'utilisateur.
|
||
Acceptation : UC-09 (calendrier) passe ; déplacer un événement d'un tiers est refusé avec le motif, pas tenté.
|
||
|
||
**P4-T07 — Outils Inbox.**
|
||
Fichiers : service de notifications existant (ajout d'une API de service consommable par les outils, pas d'accès direct aux tables depuis le registre).
|
||
Travail : `inbox_read` (résumé structuré : nouveau, à répondre, peut être effacé), `inbox_group` (type / statut / projet / page), `inbox_mark`, `inbox_archive` (masse comprise) ; confirmation obligatoire au-delà d'un seuil d'éléments (défaut proposé : 10) avec **compte exact** affiché ; bornes : les notifications d'approbation/demande d'accès sont signalées mais jamais décidées ; aucun outil de création de notification ni de modification des préférences.
|
||
Acceptation : « archive tout ce qui est lu » sur une Inbox de test de 250 éléments archive exactement les éléments lus, après une confirmation affichant « 250 » — ni 249 ni 251 (test de comptage sur fixture).
|
||
|
||
**P4-T08 — Classe `EXTERNAL_WRITE` dans la gouvernance.**
|
||
Fichiers : `app/services/agent_policies.py`, `agent_approvals`.
|
||
Travail : quatrième classe d'outils ; par défaut approbation par action (le run passe en `waiting_approval`, carte dans le panneau **ou** dans Activity pour les runs autonomes) ; politiques pré-approuvées pour les Custom Agents : tuples (agent, outil, cible) accordés par un niveau `full`, révocables, expirant par défaut (durée réglable, défaut proposé : 90 jours) et affichés dans les Settings de l'agent ; toute écriture externe exécutée écrit dans `agent_actions` avec, quand le tiers le permet, l'action inverse (supprimer le message…) sinon la mention « non annulable ».
|
||
Acceptation : il n'existe aucun chemin d'exécution d'un outil `EXTERNAL_WRITE` qui contourne soit l'approbation, soit une politique en vigueur (test par énumération des points d'entrée du registre).
|
||
|
||
### Espace fichiers
|
||
|
||
**P4-T09 — Dépôt et lecture de fichiers de conversation.**
|
||
Fichiers : routes de conversation (téléversement), nouveau `app/services/agent_files.py`, importers.
|
||
Travail : dépôt par trombone et glisser-déposer ; validation (liste blanche de types alignée sur les importers, taille `AGENT_FILE_MAX_MB`) ; stockage sous `data/uploads/agent-files/` ; outil `read_uploaded_file` : extraction texte (PDF/DOCX/PPTX), profil tabulaire (CSV/XLSX : colonnes, types devinés, aperçu), inventaire ZIP (pas d'extraction récursive, plafond décompressé) ; le LLM ne reçoit que résumés et aperçus, jamais le binaire.
|
||
Acceptation : déposer le CSV d'UC-08 donne à l'Agent un profil fidèle (noms et types de colonnes, nombre de lignes exact).
|
||
|
||
**P4-T10 — Calcul sandboxé et production de fichiers.**
|
||
Travail : `run_code_on_data` sur le moteur des Workers avec l'unique écart documenté (montage en lecture des fichiers de la conversation, répertoire de sortie en écriture, quotas renforcés) ; `produce_file` pour XLSX/PDF/DOCX/PPTX avec les bibliothèques d'export existantes ; cartes téléchargeables dans le message (`GET …/files/{id}/download` avec contrôle d'ACL de la conversation) ; `create_collection_from_file` via le pipeline d'import (déduplication comprise).
|
||
Acceptation : UC-08 de bout en bout ; un code qui tente un accès réseau ou hors du montage est bloqué par la sandbox, et le run continue avec l'échec comme résultat d'outil.
|
||
|
||
**P4-T11 — Tableau interactif de résultats dans le chat.**
|
||
Fichiers : panneau, outil `query_collection` formalisé (Annexe B du parent).
|
||
Travail : quand un résultat d'outil est tabulaire (lignes × colonnes typées), le panneau le rend en tableau en lecture (tri client, ouverture de la ligne source) ; le tableau est un artefact du message, pas une collection ; plafond de lignes affichées avec mention du total.
|
||
Acceptation : une question « quelles tâches en retard ? » rend le tableau sans ouvrir la base, et chaque ligne ouvre la bonne tâche.
|
||
|
||
**P4-T12 — Rétention des fichiers.**
|
||
Travail : `expires_at` posé au dépôt (défaut `AGENT_FILE_RETENTION_DAYS`, 30 j) sauf pour les livrables que l'utilisateur épingle/conserve ; purge ajoutée au `trash_purge_scheduler` existant ; la suppression d'une conversation supprime ses fichiers et sa mémoire (règle du parent §16.6).
|
||
Acceptation : après purge simulée, les métadonnées de run subsistent (nom, taille) mais aucun fichier expiré n'est téléchargeable.
|
||
|
||
### Comptabilité et gouvernance des modèles
|
||
|
||
**P4-T13 — `usage_meter` et journal d'usage.**
|
||
Fichiers : nouveau `app/services/usage_meter.py`, migration 42, extension de `llm_config` (taux par modèle).
|
||
Travail : à la fin de chaque run (et, pour les runs longs, par paliers), écrire la ligne de ledger depuis `agent_runs` (tokens réels remontés par le client LLM) : bucket `allowance` si le modèle est inclus, `premium` sinon ; le taux zéro du mode offline est un cas de test permanent ; webhooks `agent.credits.threshold` aux seuils 50/80/100 % des limites concernées.
|
||
Acceptation : la somme du ledger recoupe les tokens des `agent_runs` sur toute période de test ; aucun run terminé sans ligne (ou ligne à zéro explicitement offline).
|
||
|
||
**P4-T14 — Modèles gouvernés : autorisés par surface, premium, replis.**
|
||
Travail : le routeur `Auto` (Phase 2) et les sélecteurs ne voient que les modèles **autorisés pour la surface** ; les premium exigent l'activation admin et puisent dans les crédits ; un modèle désactivé disparaît (grisé pendant la transition) et les agents qui l'utilisaient basculent au prochain run sur défaut/`Auto` (comportement annoncé dans les Settings de l'agent, pas silencieux pour son propriétaire : notification) ; à limite de crédits atteinte (membre ou agent), les modèles inclus continuent et les premium s'arrêtent avec un état explicite dans le run.
|
||
Acceptation : retirer un modèle utilisé par un agent ne casse aucun run suivant et laisse une trace visible pour le propriétaire.
|
||
|
||
**P4-T15 — Tableaux d'usage et réglages IA du workspace.**
|
||
Fichiers : page de réglages (section IA & Agents du parent §7.6).
|
||
Travail : réglages de `workspace_ai_settings` (deux listes de modèles, premium, défaut, limites, `who_can_create_agents` **appliqué**, accès web par défaut) ; tableaux : usage par membre, par agent, par modèle (période, bucket, crédits), export CSV ; le coût (tokens + crédits) rejoint l'onglet Activity des agents et le détail d'un run du panneau.
|
||
Acceptation : un admin répond en moins d'une minute, depuis l'interface, à « qui a dépensé quoi, sur quel modèle, cette semaine ? ».
|
||
|
||
## 6. API livrée par la phase
|
||
|
||
| Route | Ticket |
|
||
|---|---|
|
||
| `POST /api/agent/conversations/{id}/files` · `GET …/files/{fid}/download` | T09/T10 |
|
||
| `GET/PUT /api/settings/ai` (réglages IA du workspace, admin) | T15 |
|
||
| `GET /api/settings/ai/usage` (+ `?format=csv`) | T15 |
|
||
| `POST /api/agent/connectors/slack/connect` (workspace et compte) | T02 |
|
||
| Outils (pas des routes) : Slack, Gmail, calendrier, Inbox, fichiers | T03/T05/T06/T07/T09/T10 |
|
||
| Webhooks : `agent.credits.threshold` ; champs `credits` dans `agent.run.*` | T13 |
|
||
|
||
## 7. Comportements détaillés
|
||
|
||
### 7.1 Confirmation : ce que l'utilisateur voit
|
||
|
||
Une demande d'approbation montre **l'action exacte** : pour un courriel, destinataires/objet/corps ; pour un message de canal, le canal et le texte ; pour une archive en masse, le compte et le critère. Approuver exécute **ce** contenu (hash revérifié pour le courriel) ; toute modification du contenu par l'Agent après coup exige une nouvelle approbation. Un refus laisse le run se terminer proprement avec le motif « refusé » dans la réponse.
|
||
|
||
### 7.2 Allocation, crédits, limites : les trois compteurs en pratique
|
||
|
||
```text
|
||
Run démarre → modèle résolu (Phase 2/4)
|
||
├─ modèle inclus → le run puise dans l'ALLOCATION (fenêtre glissante du workspace)
|
||
│ allocation épuisée → le run est refusé proprement (« allocation épuisée,
|
||
│ renouvellement à … »), sauf si des crédits peuvent prendre le relais (réglage)
|
||
└─ modèle premium → le run puise dans les CRÉDITS
|
||
limite membre ou limite agent atteinte → premium refusé, repli annoncé
|
||
sur un modèle inclus (jamais d'arrêt sec quand un repli existe)
|
||
Fin du run → ligne de ledger (toujours), seuils vérifiés → webhooks éventuels
|
||
```
|
||
|
||
### 7.3 Identités externes — le tableau à ne jamais violer
|
||
|
||
| Contexte | Jeton utilisé | Signature visible chez le tiers |
|
||
|---|---|---|
|
||
| Agent personnel → Slack/Gmail | Celui de l'utilisateur | L'utilisateur |
|
||
| Custom Agent → canaux accordés | Celui de l'app/du connecteur workspace | L'agent (nommé) |
|
||
| Custom Agent → Gmail | Uniquement via politique pré-approuvée par boîte | La boîte accordée |
|
||
| Tout agent → calendrier | Organisateur = l'utilisateur ou l'agenda accordé | L'organisateur réel |
|
||
|
||
### 7.4 Ce que les fichiers ne sont pas
|
||
|
||
Un fichier déposé est une **donnée**, jamais une consigne : son contenu est délimité comme les autres contenus lus (§16.4 du parent). Un tableur contenant « envoie ce fichier à… » ne déclenche rien d'autre qu'un éventuel résultat d'outil refusé par la gouvernance.
|
||
|
||
## 8. Tests
|
||
|
||
| # | Niveau | Cas |
|
||
|---|---|---|
|
||
| T-01 | Intégration | Contrat connecteur : un connecteur de test déclaratif apparaît dans All sources et fournit ses outils |
|
||
| T-02 | Intégration | Slack borné : lecture/écriture hors canal accordé impossibles (jeton restreint) |
|
||
| T-03 | Intégration | Envoi Gmail : contenu approuvé = contenu envoyé (hash) ; refus = rien n'est parti |
|
||
| T-04 | Intégration | `calendar_find_time` sur disponibilités de fixture : classement explicable, grille cohérente ; déplacement d'un événement tiers refusé |
|
||
| T-05 | Intégration | Inbox : archive en masse au compte exact après confirmation ; notifications d'approbation jamais décidées |
|
||
| T-06 | Intégration | Énumération des points d'entrée `EXTERNAL_WRITE` : aucun ne contourne approbation/politique |
|
||
| T-07 | Intégration | UC-08 complet en mode offline (extraction et production déterministes, le calcul par un « faux » code sandboxé inclus) |
|
||
| T-08 | Intégration | Sandbox : tentative réseau et tentative de sortie du montage bloquées |
|
||
| T-09 | Intégration | Ledger : somme par période = somme des runs ; run offline = ligne à 0 ; allocation épuisée = refus propre |
|
||
| T-10 | Intégration | Limite membre atteinte : premium refusé avec repli annoncé, modèles inclus toujours utilisables |
|
||
| T-11 | Intégration | Modèle retiré : l'agent bascule, le propriétaire est notifié, Activity le montre |
|
||
| T-12 | E2E | Déposer un CSV dans le chat, obtenir le tableau de résultats et le XLSX produit téléchargeable |
|
||
| T-13 | E2E | Trouver un créneau à trois et réserver depuis la grille |
|
||
| T-14 | Non-régression | Les connecteurs en lecture seule fonctionnent inchangés pour les utilisateurs sans consentement d'écriture |
|
||
|
||
## 9. Critères d'acceptation
|
||
|
||
- [ ] UC-08, UC-09 et UC-10 passent de bout en bout.
|
||
- [ ] Aucune écriture externe sans approbation ou politique pré-approuvée en vigueur (T-06).
|
||
- [ ] Aucun run sans ligne au ledger ; les tableaux d'usage recoupent les runs.
|
||
- [ ] Un Custom Agent déclenché par une mention dans un canal accordé répond dans ce canal et nulle part ailleurs.
|
||
- [ ] La parité fonctionnelle du document parent §3 est atteinte : la Phase 5 n'a plus de fonctionnalité à ajouter, seulement à durcir.
|
||
|
||
## 10. Risques spécifiques et vigilance
|
||
|
||
| Risque | Vigilance |
|
||
|---|---|
|
||
| Consentements OAuth d'écriture trop larges demandés d'un bloc | Le second consentement est séparé, nommé par domaine (courriel **ou** calendrier), et la lecture seule reste un état complet et digne |
|
||
| Un envoi approuvé puis modifié par une reprise de run | Hash du contenu dans l'approbation (T05) ; un run repris après refus repart d'une demande nouvelle |
|
||
| Explosion des coûts par un déclencheur de messagerie bavard | Les plafonds de la Phase 3 s'appliquent, plus les budgets crédits désormais réels ; l'indicateur d'activité (`show_typing`) est désactivable et les filtres mots-clés sont proposés par défaut |
|
||
| Le montage fichiers de la sandbox devient une brèche | C'est l'unique écart au modèle Workers : revue de sécurité dédiée avant T10, chemins canonisés et vérifiés sous le répertoire de la conversation, quotas bas par défaut |
|
||
| L'allocation « fenêtre glissante » mal comprise crée des refus surprenants | L'état courant de l'allocation est visible par l'utilisateur dans ses réglages, avec l'heure de renouvellement calculée depuis le ledger — jamais un message « réessayez plus tard » sans date |
|
||
| Slack change ses API/scopes | Le connecteur isole les appels derrière son service ; les tests d'intégration Slack utilisent un double d'API, les tests réels sont manuels et listés dans la grille de test |
|
||
|
||
## 11. Ordre d'exécution
|
||
|
||
```text
|
||
T01 ──┬── T02 ── T03 ── T04
|
||
├── T05 ──┐
|
||
├── T06 ├── T08 (gouvernance, avant toute mise en service des écritures)
|
||
└── T07 ──┘
|
||
T09 ── T10 ── T11 ; T12 après T10
|
||
T13 ── T14 ── T15
|
||
Les trois chantiers (externe / fichiers / comptabilité) sont parallélisables,
|
||
mais T08 et T13 sont les portes : pas d'écriture externe en production sans
|
||
gouvernance complète, pas de premium sans comptage.
|
||
```
|
||
|
||
## 12. Définition de « terminé »
|
||
|
||
Critères du §9 verts ; revue de sécurité passée sur `EXTERNAL_WRITE` et sur le montage fichiers ; deux semaines de fonctionnement avec le ledger en observation (écarts ledger/runs à zéro) ; document parent annoté (« Phase 4 livrée — parité atteinte ») ; aide in-app complète pour les nouveaux réglages.
|
||
|
||
---
|
||
|
||
*Document de phase 4/5 — dépend des Phases 1 à 3 ; la Phase 5 ne fait que durcir et étendre.*
|