Application OrbitBrain, projets et équipes

Brain, projets et équipes

Projets Studio comme données, primitives du Brain, ingestion en flux, onboarding et surfaces d’équipe (QC, Concepts, Relecture, Academy, Développeurs).

Projets, Brain et onboarding (ADR 0020)

  • Les projets Studio sont des données. Workspace (l'équipe) → Product (nom, slug = id, site, statut, créateur) → ProductConnection (dépôt GitHub, analytics, réseaux, hôtes de références ; validée par validateProductConnection de packages/connectors, config non secrète). Un projet lit le contexte des Spaces du Brain qui lui sont liés (SpaceBinding, ADR 0018). Le catalogue des projets (@orbit/products, process-wide) se recharge quand la séquence catalog_version a bougé (triggers sur Product, Memory, SpaceBinding, ProductConnection) : une lecture sans verrou par requête membre, et un rechargement après chaque écriture. Un id que personne n'a créé est une erreur.
  • Le Brain (apps/web/src/modules/brain/) : BrainSpace (un domaine de contexte d'un workspace : une marque, une app, le travail, la vie perso…, dont le gabarit nomme les cinq piliers) → Memory (pilier IDENTITY, GUIDELINES, KNOWLEDGE, ITEMS ou PEOPLE, imbrication par parentId, provenance source/sourceRef, clé stable sourceKey). Gabarits et libellés : packages/engine/src/brain/templates.ts. Toute lecture et toute écriture passent par le workspace du membre : un Space d'un autre compte répond comme un Space inconnu.
  • Capacité et facturation du Brain : les montants, les deux paywalls et le quota sont décrits dans Mémoire & CU, Économie & paywall et Facturation Stripe. Dans le code : Workspace.brainCapacityCu (0 tant qu'Orbit n'est pas activé), activationRequired puis capacityFull (sous le verrou du workspace), les lectures de sources par le compteur du Brain (createBrainMeter, table BrainUsage : Orbit paie le fournisseur, jamais les crédits Studio du membre, et jamais pour un compte non activé), un plafond de 20 lectures par workspace et par 24 h, et le quota mensuel de lectures MCP/REST (BrainReadCounter, 402 quota_exceeded, jamais de facturation à l'usage).
  • Sources (modules/brain/ingest.ts) : un site est lu par readSiteForBrain (packages/engine/src/brain/site-reader.ts) ; relu, il met à jour les mêmes Memories (sourceKey stable), donc les ids et le graphe restent en place. Un PDF ou une image (4 Mo au plus, type lu dans les octets) est rangé sous brain/<space>/, puis lu : un PDF gratuitement par unpdf, une image décrite par le modèle du catalogue, sur le compteur du Brain. Un échec retire le fichier et n'écrit rien ; supprimer la Memory supprime son fichier.
  • Le Brain vivant : l'apparition d'un nœud n'est jamais un effet décoratif ni passable (ni Échap ni clic de fond ne l'ignorent ; seule la préférence système prefers-reduced-motion l'évite) : c'est le flux réel du Brain qui se nourrit. Trois chemins l'alimentent.
    1. Lecture d'un site ou d'un fichier : POST /api/brain/spaces/<id>/ingest (<id> = un Space du workspace, ou new pour créer le Space de cette première source), en NDJSON (modules/brain/stream.ts). Chaque Memory est écrite dans sa propre transaction (writeMemories avec onWritten) puis annoncée juste après : événements space (si créé), memory (la Memory et les jauges du Space), puis done (vue fraîche, liste des Spaces, notice française) ou error (code et message français). En-tête Idempotency-Key obligatoire : le rejeu d'une même clé n'est ni facturé ni écrit deux fois (le compteur du Brain le refuse). Porte brain.write, rôle relu en base ; un Space d'un autre workspace répond 404 comme un Space inconnu, avant l'ouverture du flux.
    2. Écritures simples (une note, une source déclarée, modifier, supprimer) : actions serveur qui rendent la vue fraîche ; le nœud d'une note ajoutée à la main apparaît lui aussi avec son apparition.
    3. Écritures venues d'ailleurs (MCP, API REST, autre onglet) : GET /api/brain/spaces/<id>/pulse?since=<curseur> rend les ids et les updatedAt modifiés depuis le curseur (inclusif) et le nombre de Memories (modules/brain/pulse.ts : une requête bornée par le Space, pas de corps, pas de N+1 ; Space étranger = 404 comme inconnu). Le graphe l'interroge toutes les 3 s pour le Space ouvert, se met en pause onglet masqué, et lorsque le résultat diffère (id inconnu, date plus récente, nombre différent) relit le Space et fait apparaître les nouveaux nœuds.
  • Apprentissages Studio : ce qu'un concept a appris en QC est une observation de l'outil, calculée depuis les concepts (team/learning.ts), jamais écrite dans le Brain (ADR 0018).
  • Onboarding (/onboarding, src/workspace/onboarding.ts) : facultatif. Après la connexion, on arrive sur /brain : le Brain vide est l'onboarding. Le guide reste accessible depuis le menu (prénom et photo, intention, projet, connexions, première création). Une question par écran, « Passer » partout, état par membre en base, chaque écran écrit dans OnboardingEvent.

Surfaces d'équipe (studio/21)

Les surfaces d'équipe restent sous Studio, tandis que les surfaces globales du compte vivent au premier niveau du cockpit. freeId ne crée jamais un projet qc, concepts ou review.

  • Academy (/academy, puis /academy/[slug]) : catalogue éditorial in-app, filtré par rôle, avec compteur dans le rail. Docs reste une ressource externe distincte.

  • Développeurs : /developers/api gère les clés orb_… du compte et /developers/mcp configure le serveur MCP. Une clé couvre plusieurs projets ; l'isolation Workspace reste une notion DB interne, jamais une navigation produit.

  • QC (/studio/qc, review, src/team/qc.ts) : les créations de l'équipe par statut et par produit ; approuver, ou rejeter avec l'une des neuf raisons fermées (StudioAssetRejection). Chaque verdict écrit qc.approved ou qc.rejected dans StudioAuditLog, qui est l'historique de la création. Une création livrée ne change plus de verdict.

  • Concepts (/studio/concepts, lecture pour tous, écriture concepts.edit, src/team/concepts.ts) : titre, angle, message, persona ; valider, archiver (CreativeConcept.archivedAt), restaurer ; « Générer depuis ce concept » ouvre le composer du produit avec ?idea=.

  • Relecture (/studio/review, review, src/team/review.ts) : le texte d'une création (accroche, sinon le prompt) contre checkCopyForm et les consignes du produit (aujourd'hui via le Brain legacy : une entrée dont ou titrée « À éviter » liste un terme interdit par ligne). OK est refusé tant qu'un constat bloquant reste ; chaque relecture est une ligne CopyReview.