Skip to main content
Glama

add_kind_node

Creates a node for one of the 4 polymorphic diagrams, ALL LIVE since May 2026: architecture, process, customer journey, cap table. The kind parameter must match the project's primary_kind (unless the user explicitly asks to mix). metadata is strictly validated per kind; the exact shape of each kind is described by get_playbook (e.g. { archType: 'service', technology: 'nodejs' } for arch, { processType: 'task', taskType: 'user' } for process).

Input Schema

NameRequiredDescriptionDefault
xNoX position in pixels (React Flow). When omitted (with y/width/height), the field lets resolveAutoPosition place the node automatically according to its kind (e.g. a process task lands in its lane, a journey step in its (phase, swimlane) cell).
yNoY position in pixels (React Flow). See x — absent = auto-layout.
idYesUnique ID of the block (kebab-case, e.g. 'api-gateway', 'orders-service')
descNoLong description.
kindYesDiagram type: arch | process | journey | captable ONLY ('org' belongs to add_cell, 'entity' to add_entity). Must match the project's primary_kind unless the user explicitly asks to mix.
nameYesShort name displayed on the node.
labelNoSecondary label (subtitle).
widthNoWidth in pixels. Absent = default width of the kind.
heightNoHeight in pixels. Absent = default height of the kind.
colorKeyNoColor (default depends on the kind).
metadataYesKind-specific metadata — the shape depends on the value of `kind` above: arch → { archType (required: service|datastore|queue|gateway|external|lambda|batch|network|cdn|cache), technology?, cloudProvider?, region?, cost?, slo?, dataClassification?, ... } ; process → { processType (required: task|event-start|event-end|gateway-xor|gateway-and|gateway-or|subprocess|lane), laneId?, taskType?, duration?, sla?, isBottleneck?, complianceTags?, ... } ; journey → { journeyType (required: phase|step|touchpoint|pain|opportunity|headline), phaseId?, swimlane?, emotion? (-2..+2), isMomentOfTruth?, ... } ; captable → { captableType (required: 'holder'|'round') then either holderType/securityType/shares/securityRound/... or name/date/preMoneyValuation/amountRaised/... }. Each field is documented individually in its own schema (see archMetadataSchema / processMetadataSchema / journeyMetadataSchema / captableMetadataSchema server-side) — this description remains the only entry point visible to an external MCP client.
parentIdNoID of the parent (container or network).
expectedProjectIdNoUUID of the project targeted by THIS call. ACTUALLY targets this project instead of the session project. Refused without changing anything if access is not granted.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed14 schema fields changed
    • changedInput schema / properties / colorKey / description
      Previous value: -"Couleur (défaut dépend du kind)."New value: +"Color (default depends on the kind)."
    • changedInput schema / properties / desc / description
      Previous value: -"Description longue."New value: +"Long description."
    • changedInput schema / properties / expectedProjectId / description
      Previous value: -"UUID du projet visé par CET appel. Cible RÉELLEMENT ce projet au lieu du projet de session. Refusé sans rien modifier si l'accès n'est pas accordé."New value: +"UUID of the project targeted by THIS call. ACTUALLY targets this project instead of the session project. Refused without changing anything if access is not granted."
    • changedInput schema / properties / height / description
      Previous value: -"Hauteur en pixels. Absent = hauteur par défaut du kind."New value: +"Height in pixels. Absent = default height of the kind."
    • changedInput schema / properties / id / description
      Previous value: -"ID unique de la cellule (kebab-case, ex: 'api-gateway', 'orders-service')"New value: +"Unique ID of the block (kebab-case, e.g. 'api-gateway', 'orders-service')"
    • changedInput schema / properties / kind / description
      Previous value: -"Type de diagramme : arch | process | journey | captable UNIQUEMENT ('org' relève d'add_cell, 'entity' d'add_entity). Doit matcher le primary_kind du projet sauf si l'utilisateur demande explicitement de mixer."New value: +"Diagram type: arch | process | journey | captable ONLY ('org' belongs to add_cell, 'entity' to add_entity). Must match the project's primary_kind unless the user explicitly asks to mix."
    • changedInput schema / properties / label / description
      Previous value: -"Label secondaire (sous-titre)."New value: +"Secondary label (subtitle)."
    • changedInput schema / properties / metadata / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "archType": {
      -        "description": "Nature du composant d'architecture — détermine l'icône et la couleur par défaut du nœud. 'service' = appli/API, 'datastore' = DB/storage, 'queue' = message broker, 'gateway' = API gateway/LB, 'external' = dépendance tierce hors du périmètre, 'lambda' = fonction serverless, 'batch' = job/cron, 'network' = VPC/subnet/segment réseau, 'cdn' = edge/CDN, 'cache' = cache mémoire (Redis, Memcached...).",
      -        "enum": [
      -          "service",
      -          "datastore",
      -          "queue",
      -          "gateway",
      -          "external",
      -          "lambda",
      -          "batch",
      -          "network",
      -          "cdn",
      -          "cache"
      -        ],
      -        "type": "string"
      -      },
      -      "capacity": {
      -        "description": "Dimensionnement libre (ex: '4 vCPU / 8GB', 'db.r6g.large', 'auto-scale 2-10 pods').",
      -        "maxLength": 120,
      -        "type": "string"
      -      },
      -      "cloudProvider": {
      -        "description": "Fournisseur cloud hébergeant ce composant.",
      -        "enum": [
      -          "aws",
      -          "gcp",
      -          "azure",
      -          "on-prem"
      -        ],
      -        "type": "string"
      -      },
      -      "cost": {
      -        "additionalProperties": false,
      -        "description": "Coût mensuel estimé — affiché sur le nœud si présent.",
      -        "properties": {
      -          "monthlyUsd": {
      -            "description": "Coût mensuel estimé du composant, en USD.",
      -            "maximum": 1000000000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "note": {
      -            "description": "Précision libre sur le coût (ex: 'tier réservé 1 an', 'estimation à 10k req/j').",
      -            "maxLength": 120,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "monthlyUsd"
      -        ],
      -        "type": "object"
      -      },
      -      "dataClassification": {
      -        "description": "Sensibilité des données traitées/stockées par ce composant : 'public' | 'internal' | 'confidential' | 'pii' | 'secret'. Utilisée pour mettre en évidence les composants à surveiller (ex: tout ce qui touche 'pii').",
      -        "enum": [
      -          "public",
      -          "internal",
      -          "confidential",
      -          "pii",
      -          "secret"
      -        ],
      -        "type": "string"
      -      },
      -      "providerLogo": {
      -        "description": "Logo de service tiers à afficher sur le nœud (ex: 'aws', 'stripe', 'supabase') — purement visuel, indépendant de cloudProvider.",
      -        "enum": [
      -          "aws",
      -          "gcp",
      -          "azure",
      -          "cloudflare",
      -          "vercel",
      -          "fly",
      -          "openai",
      -          "anthropic",
      -          "mistral",
      -          "cohere",
      -          "huggingface",
      -          "replicate",
      -          "pinecone",
      -          "qdrant",
      -          "weaviate",
      -          "chroma",
      -          "postgres",
      -          "mysql",
      -          "mongodb",
      -          "redis",
      -          "snowflake",
      -          "bigquery",
      -          "clickhouse",
      -          "kafka",
      -          "sqs",
      -          "pubsub",
      -          "rabbitmq",
      -          "stripe",
      -          "twilio",
      -          "sendgrid",
      -          "resend",
      -          "auth0",
      -          "clerk",
      -          "supabase",
      -          "datadog",
      -          "sentry",
      -          "segment",
      -          "mixpanel",
      -          "github",
      -          "linear",
      -          "notion",
      -          "slack"
      -        ],
      -        "type": "string"
      -      },
      -      "publicAccess": {
      -        "description": "true si le composant est exposé publiquement sur internet (pas seulement en interne).",
      -        "type": "boolean"
      -      },
      -      "region": {
      -        "description": "Région d'hébergement (ex: 'eu-west-3', 'cdg1').",
      -        "maxLength": 40,
      -        "type": "string"
      -      },
      -      "slo": {
      -        "additionalProperties": false,
      -        "description": "Objectifs de niveau de service (latence, disponibilité).",
      -        "properties": {
      -          "availabilityPct": {
      -            "description": "Disponibilité cible, en % (ex: 99.9).",
      -            "maximum": 100,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "p99LatencyMs": {
      -            "description": "Latence p99 cible ou observée, en millisecondes.",
      -            "maximum": 60000,
      -            "minimum": 0,
      -            "type": "number"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "technology": {
      -        "description": "Techno/framework concret (ex: 'Node.js 22', 'Amazon Aurora PostgreSQL 15.4 Serverless v2').",
      -        "maxLength": 120,
      -        "type": "string"
      -      },
      -      "trustBoundary": {
      -        "description": "Nom de la zone de confiance/périmètre de sécurité (ex: 'DMZ', 'VPC privé', 'zone PCI') — les composants partageant le même trustBoundary sont visuellement groupables.",
      -        "maxLength": 40,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "archType"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "actor": {
      -        "description": "Acteur/rôle exécutant cette tâche précise, si différent de l'acteur par défaut de la lane.",
      -        "maxLength": 80,
      -        "type": "string"
      -      },
      -      "collapsed": {
      -        "description": "true pour replier visuellement un subprocess (masque ses enfants sur le canvas).",
      -        "type": "boolean"
      -      },
      -      "complianceTags": {
      -        "description": "Tags réglementaires applicables à cette étape (ex: 'gdpr', 'sox', 'pci', 'hipaa', 'kyc', 'aml', 'iso27001', 'four-eyes').",
      -        "items": {
      -          "maxLength": 20,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "maxItems": 8,
      -        "type": "array"
      -      },
      -      "cost": {
      -        "additionalProperties": false,
      -        "description": "Coût de traitement par dossier pour cette étape.",
      -        "properties": {
      -          "note": {
      -            "description": "Précision libre sur le coût.",
      -            "maxLength": 120,
      -            "type": "string"
      -          },
      -          "perCaseUsd": {
      -            "description": "Coût de traitement par dossier/instance, en USD.",
      -            "maximum": 1000000,
      -            "minimum": 0,
      -            "type": "number"
      -          }
      -        },
      -        "required": [
      -          "perCaseUsd"
      -        ],
      -        "type": "object"
      -      },
      -      "duration": {
      -        "additionalProperties": false,
      -        "description": "Durée de traitement typique de cette étape.",
      -        "properties": {
      -          "unit": {
      -            "description": "Unité: minutes, heures ou jours.",
      -            "enum": [
      -              "min",
      -              "h",
      -              "d"
      -            ],
      -            "type": "string"
      -          },
      -          "value": {
      -            "description": "Valeur numérique de la durée.",
      -            "exclusiveMinimum": 0,
      -            "maximum": 100000,
      -            "type": "number"
      -          }
      -        },
      -        "required": [
      -          "value",
      -          "unit"
      -        ],
      -        "type": "object"
      -      },
      -      "executionPct": {
      -        "description": "% des instances du process qui passent réellement par cette étape (100 = chemin toujours emprunté).",
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "isBottleneck": {
      -        "description": "true pour marquer visuellement cette étape comme goulot d’étranglement identifié (durée/SLA problématique).",
      -        "type": "boolean"
      -      },
      -      "laneId": {
      -        "description": "ID de la lane parente (cellule processType='lane') à laquelle rattacher cette task/event — kebab-case, comme retourné par add_swimlane (ex: 'lane-sales').",
      -        "type": "string"
      -      },
      -      "processType": {
      -        "description": "Rôle BPMN-lite de la cellule — détermine sa forme sur le canvas : 'task' (rectangle), 'event-start'/'event-end' (cercle début/fin), 'event-intermediate-timer'/'event-intermediate-error' (cercle intermédiaire), 'gateway-xor'/'gateway-and'/'gateway-or' (losange de décision), 'subprocess' (rectangle double-bordure), 'lane' (couloir — normalement créé via add_swimlane, pas via add_kind_node directement).",
      -        "enum": [
      -          "task",
      -          "event-start",
      -          "event-end",
      -          "event-intermediate-timer",
      -          "event-intermediate-error",
      -          "gateway-xor",
      -          "gateway-and",
      -          "gateway-or",
      -          "subprocess",
      -          "lane"
      -        ],
      -        "type": "string"
      -      },
      -      "sla": {
      -        "additionalProperties": false,
      -        "description": "Délai maximum contractuel/cible pour cette étape (comparé à duration pour détecter les dépassements).",
      -        "properties": {
      -          "unit": {
      -            "description": "Unité: minutes, heures ou jours.",
      -            "enum": [
      -              "min",
      -              "h",
      -              "d"
      -            ],
      -            "type": "string"
      -          },
      -          "value": {
      -            "description": "Valeur numérique de la durée.",
      -            "exclusiveMinimum": 0,
      -            "maximum": 100000,
      -            "type": "number"
      -          }
      -        },
      -        "required": [
      -          "value",
      -          "unit"
      -        ],
      -        "type": "object"
      -      },
      -      "swimlaneOrder": {
      -        "description": "Ordre vertical au sein de la lane (rarement utilisé — à défaut, l’ordre des lanes suit `order`, puis l’id).",
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "taskType": {
      -        "description": "Type d'exécutant pour une task : 'user' (humain via UI), 'service' (système/API), 'manual' (humain hors-système, ex: papier), 'script' (automatisation batch).",
      -        "enum": [
      -          "user",
      -          "service",
      -          "manual",
      -          "script"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "processType"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "channel": {
      -        "description": "Canal principal via lequel cette interaction a lieu.",
      -        "enum": [
      -          "web",
      -          "email",
      -          "app",
      -          "phone",
      -          "in-person",
      -          "social",
      -          "sms",
      -          "chat",
      -          "push"
      -        ],
      -        "type": "string"
      -      },
      -      "channels": {
      -        "description": "Canaux multiples si le touchpoint est multi-canal (channel seul suffit pour un canal unique).",
      -        "items": {
      -          "enum": [
      -            "web",
      -            "email",
      -            "app",
      -            "phone",
      -            "in-person",
      -            "social",
      -            "sms",
      -            "chat",
      -            "push"
      -          ],
      -          "type": "string"
      -        },
      -        "maxItems": 8,
      -        "type": "array"
      -      },
      -      "emotion": {
      -        "anyOf": [
      -          {
      -            "const": -2,
      -            "type": "number"
      -          },
      -          {
      -            "const": -1,
      -            "type": "number"
      -          },
      -          {
      -            "const": 0,
      -            "type": "number"
      -          },
      -          {
      -            "const": 1,
      -            "type": "number"
      -          },
      -          {
      -            "const": 2,
      -            "type": "number"
      -          }
      -        ],
      -        "description": "Score émotionnel du client à cette étape, de -2 (très négatif/frustration) à +2 (très positif/enchantement), 0 = neutre. N'est PAS rendu comme courbe sur le canvas automatiquement (voir compute_emotion_curve pour l'agréger) — un score ≤ -1 signale typiquement un point de friction à documenter via une cellule 'pain' associée."
      -      },
      -      "isMomentOfTruth": {
      -        "description": "true pour marquer un instant décisif qui influence fortement la perception globale du client (mis en évidence visuellement).",
      -        "type": "boolean"
      -      },
      -      "journeyType": {
      -        "description": "Rôle de la cellule dans la carte de parcours : 'phase' (grande étape, colonne d'en-tête), 'step' (action concrète de l'utilisateur), 'touchpoint' (point de contact avec un canal/produit), 'pain' (point de friction/irritant), 'opportunity' (piste d'amélioration identifiée), 'headline' (bloc de titre/contexte libre).",
      -        "enum": [
      -          "phase",
      -          "step",
      -          "touchpoint",
      -          "pain",
      -          "opportunity",
      -          "headline"
      -        ],
      -        "type": "string"
      -      },
      -      "metrics": {
      -        "description": "Indicateurs chiffrés rattachés à cette étape (NPS, taux, durée...).",
      -        "items": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "delta": {
      -              "description": "Variation affichée à côté de la valeur (ex: '+5 pts', '-2%').",
      -              "maxLength": 20,
      -              "type": "string"
      -            },
      -            "hint": {
      -              "description": "Info-bulle explicative (source de la donnée, période de mesure...).",
      -              "maxLength": 120,
      -              "type": "string"
      -            },
      -            "label": {
      -              "description": "Nom court de la métrique (ex: 'NPS', 'Taux de conversion').",
      -              "maxLength": 40,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "trend": {
      -              "description": "Sens de la flèche de tendance affichée avec delta.",
      -              "enum": [
      -                "up",
      -                "down",
      -                "flat"
      -              ],
      -              "type": "string"
      -            },
      -            "value": {
      -              "description": "Valeur affichée (ex: '42', '12.3%') — texte libre, pas forcément numérique.",
      -              "maxLength": 40,
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label",
      -            "value"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 6,
      -        "type": "array"
      -      },
      -      "orderInPhase": {
      -        "description": "Ordre horizontal au sein de la phase (0 = en premier). Absent = append à droite.",
      -        "maximum": 1000,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "phaseId": {
      -        "description": "ID de la phase parente (cellule journeyType='phase', créée via add_journey_phase) — positionne la cellule dans la bonne colonne.",
      -        "type": "string"
      -      },
      -      "quote": {
      -        "additionalProperties": false,
      -        "description": "Verbatim client illustrant ce point du parcours.",
      -        "properties": {
      -          "author": {
      -            "description": "Attribution (ex: 'Client B2B, 50 employés', prénom si connu).",
      -            "maxLength": 80,
      -            "type": "string"
      -          },
      -          "text": {
      -            "description": "Citation verbatim du client/utilisateur.",
      -            "maxLength": 280,
      -            "minLength": 1,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "text"
      -        ],
      -        "type": "object"
      -      },
      -      "severity": {
      -        "description": "Gravité d'un pain point ou priorité d'une opportunity.",
      -        "enum": [
      -          "low",
      -          "medium",
      -          "high"
      -        ],
      -        "type": "string"
      -      },
      -      "swimlane": {
      -        "description": "Couloir horizontal (modèle service blueprint) : 'customer' (actions visibles du client), 'frontstage' (interactions client-visibles côté entreprise), 'backstage' (opérations internes invisibles du client), 'support' (systèmes/process support).",
      -        "enum": [
      -          "customer",
      -          "frontstage",
      -          "backstage",
      -          "support"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "journeyType"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "oneOf": [
      -      {
      -        "additionalProperties": false,
      -        "properties": {
      -          "captableType": {
      -            "const": "holder",
      -            "description": "Discriminant fixe — identifie cette cellule comme un actionnaire/détenteur de titres (par opposition à un round).",
      -            "type": "string"
      -          },
      -          "holderType": {
      -            "description": "Catégorie de détenteur : 'founder' (co-fondateur), 'employee' (salarié avec BSPCE/options), 'investor' (VC/business angel), 'pool' (réserve ESOP non-allouée), 'entity' (personne morale, holding, SPV).",
      -            "enum": [
      -              "founder",
      -              "employee",
      -              "investor",
      -              "pool",
      -              "entity"
      -            ],
      -            "type": "string"
      -          },
      -          "isConcentrated": {
      -            "description": "true pour marquer ce holder comme signal de concentration (utilisé par validate_captable).",
      -            "type": "boolean"
      -          },
      -          "liquidationPreference": {
      -            "additionalProperties": false,
      -            "description": "Préférence de liquidation applicable (typique pour preferred).",
      -            "properties": {
      -              "dividendRatePct": {
      -                "description": "Taux de dividende cumulatif, en % annuel (ex: 8 pour 8%/an, défaut NVCA). Court en intérêt SIMPLE sur le montant investi entre la date du round et la date de sortie, ajouté par-dessus la préférence. Omettre pour aucun dividende.",
      -                "maximum": 100,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "multiplier": {
      -                "description": "Multiple de préférence de liquidation (ex: 1 = 1×, 2 = 2×) — montant récupéré en priorité = multiplier × montant investi.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 10,
      -                "type": "number"
      -              },
      -              "participating": {
      -                "description": "true = preferred \"participating\" (touche la préférence de liquidation PUIS participe aussi au pro-rata résiduel avec les common) ; false = \"non-participating\" (touche le max entre la préférence ET la conversion pro-rata en common, jamais les deux).",
      -                "type": "boolean"
      -              }
      -            },
      -            "required": [
      -              "multiplier",
      -              "participating"
      -            ],
      -            "type": "object"
      -          },
      -          "pricePerShare": {
      -            "description": "Prix payé par action lors de l'émission — absent pour un SAFE non converti.",
      -            "maximum": 1000000000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "safeTerms": {
      -            "additionalProperties": false,
      -            "description": "Termes du SAFE — requis si securityType='safe', ignoré sinon.",
      -            "properties": {
      -              "capBasis": {
      -                "description": "Base sur laquelle s'applique valuationCap. 'post-money' = convention YC SAFE v2 (la plus courante depuis 2018).",
      -                "enum": [
      -                  "post-money",
      -                  "pre-money"
      -                ],
      -                "type": "string"
      -              },
      -              "discountPct": {
      -                "description": "Remise en % sur le prix par action du prochain priced round (ex: 20 pour 20% de discount).",
      -                "maximum": 100,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "investmentUsd": {
      -                "description": "Montant investi via ce SAFE, en USD (ou monnaie du projet).",
      -                "maximum": 1000000000000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "mfn": {
      -                "description": "Most Favored Nation — true si ce SAFE bénéficie automatiquement des termes plus favorables accordés à un SAFE ultérieur.",
      -                "type": "boolean"
      -              },
      -              "valuationCap": {
      -                "description": "Plafond de valorisation du SAFE — au-delà, le SAFE convertit comme si la valorisation était plafonnée à ce montant.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 1000000000000,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "securityRound": {
      -            "description": "ID du round (cellule captableType='round') dans lequel ce titre a été émis — absent = émission fondatrice (t=0). UUID ou kebab-case, comme le reste des ids de cellule.",
      -            "type": "string"
      -          },
      -          "securityType": {
      -            "description": "Type de titre détenu : 'common' (actions ordinaires, typiquement fondateurs), 'preferred' (actions de préférence, typiquement investisseurs priced round), 'safe' (SAFE non converti — voir safeTerms), 'convertible' (obligation convertible), 'option' (stock-options/BSPCE non exercées).",
      -            "enum": [
      -              "common",
      -              "preferred",
      -              "safe",
      -              "convertible",
      -              "option"
      -            ],
      -            "type": "string"
      -          },
      -          "shares": {
      -            "description": "Nombre de parts/actions détenues (entier ou décimal selon la granularité du cap table).",
      -            "maximum": 1000000000000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "vestingSchedule": {
      -            "additionalProperties": false,
      -            "description": "Calendrier de vesting applicable à ces parts (typique pour founder/employee).",
      -            "properties": {
      -              "cliffMonths": {
      -                "description": "Durée du cliff en mois (période avant laquelle 0 part n'est acquise, ex: 12).",
      -                "maximum": 120,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "startDate": {
      -                "description": "Date de début du vesting (YYYY-MM-DD).",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "totalMonths": {
      -                "description": "Durée totale du vesting en mois (ex: 48 pour un vesting standard 4 ans).",
      -                "maximum": 240,
      -                "minimum": 1,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "startDate",
      -              "cliffMonths",
      -              "totalMonths"
      -            ],
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "captableType",
      -          "holderType",
      -          "securityType",
      -          "shares"
      -        ],
      -        "type": "object"
      -      },
      -      {
      -        "additionalProperties": false,
      -        "properties": {
      -          "amountRaised": {
      -            "description": "Montant total levé lors de ce round.",
      -            "maximum": 1000000000000000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "captableType": {
      -            "const": "round",
      -            "description": "Discriminant fixe — identifie cette cellule comme un tour de financement (par opposition à un holder).",
      -            "type": "string"
      -          },
      -          "date": {
      -            "description": "Date de closing du round (YYYY-MM-DD).",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          },
      -          "esopRefreshPct": {
      -            "description": "% de refresh du pool ESOP effectué à l'occasion de ce round.",
      -            "maximum": 100,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "name": {
      -            "description": "Nom du round (ex: 'Seed', 'Series A', 'Bridge').",
      -            "maxLength": 80,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "preMoneyValuation": {
      -            "description": "Valorisation pré-money du round, en monnaie du projet.",
      -            "maximum": 1000000000000000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "riskTags": {
      -            "description": "Signaux de risque associés à ce round : 'down-round', 'concentration', 'underwater-options', 'anti-dilution'.",
      -            "items": {
      -              "enum": [
      -                "down-round",
      -                "concentration",
      -                "underwater-options",
      -                "anti-dilution"
      -              ],
      -              "type": "string"
      -            },
      -            "maxItems": 8,
      -            "type": "array"
      -          },
      -          "termSheetNote": {
      -            "description": "Note libre sur les conditions négociées (clauses particulières, board seat, pro-rata rights...).",
      -            "maxLength": 160,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "captableType",
      -          "name",
      -          "date",
      -          "preMoneyValuation",
      -          "amountRaised"
      -        ],
      -        "type": "object"
      -      }
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "archType": {
      +        "description": "Nature of the architecture component — determines the node's default icon and color. 'service' = app/API, 'datastore' = DB/storage, 'queue' = message broker, 'gateway' = API gateway/LB, 'external' = third-party dependency outside the perimeter, 'lambda' = serverless function, 'batch' = job/cron, 'network' = VPC/subnet/network segment, 'cdn' = edge/CDN, 'cache' = in-memory cache (Redis, Memcached...).",
      +        "enum": [
      +          "service",
      +          "datastore",
      +          "queue",
      +          "gateway",
      +          "external",
      +          "lambda",
      +          "batch",
      +          "network",
      +          "cdn",
      +          "cache"
      +        ],
      +        "type": "string"
      +      },
      +      "capacity": {
      +        "description": "Free-form sizing (e.g. '4 vCPU / 8GB', 'db.r6g.large', 'auto-scale 2-10 pods').",
      +        "maxLength": 120,
      +        "type": "string"
      +      },
      +      "cloudProvider": {
      +        "description": "Cloud provider hosting this component.",
      +        "enum": [
      +          "aws",
      +          "gcp",
      +          "azure",
      +          "on-prem"
      +        ],
      +        "type": "string"
      +      },
      +      "cost": {
      +        "additionalProperties": false,
      +        "description": "Estimated monthly cost — shown on the node when present.",
      +        "properties": {
      +          "monthlyUsd": {
      +            "description": "Estimated monthly cost of the component, in USD.",
      +            "maximum": 1000000000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "note": {
      +            "description": "Free-form note on the cost (e.g. '1-year reserved tier', 'estimate at 10k req/day').",
      +            "maxLength": 120,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "monthlyUsd"
      +        ],
      +        "type": "object"
      +      },
      +      "dataClassification": {
      +        "description": "Sensitivity of the data processed/stored by this component: 'public' | 'internal' | 'confidential' | 'pii' | 'secret'. Used to highlight the components to watch (e.g. anything that touches 'pii').",
      +        "enum": [
      +          "public",
      +          "internal",
      +          "confidential",
      +          "pii",
      +          "secret"
      +        ],
      +        "type": "string"
      +      },
      +      "providerLogo": {
      +        "description": "Third-party service logo to show on the node (e.g. 'aws', 'stripe', 'supabase') — purely visual, independent of cloudProvider.",
      +        "enum": [
      +          "aws",
      +          "gcp",
      +          "azure",
      +          "cloudflare",
      +          "vercel",
      +          "fly",
      +          "openai",
      +          "anthropic",
      +          "mistral",
      +          "cohere",
      +          "huggingface",
      +          "replicate",
      +          "pinecone",
      +          "qdrant",
      +          "weaviate",
      +          "chroma",
      +          "postgres",
      +          "mysql",
      +          "mongodb",
      +          "redis",
      +          "snowflake",
      +          "bigquery",
      +          "clickhouse",
      +          "kafka",
      +          "sqs",
      +          "pubsub",
      +          "rabbitmq",
      +          "stripe",
      +          "twilio",
      +          "sendgrid",
      +          "resend",
      +          "auth0",
      +          "clerk",
      +          "supabase",
      +          "datadog",
      +          "sentry",
      +          "segment",
      +          "mixpanel",
      +          "github",
      +          "linear",
      +          "notion",
      +          "slack"
      +        ],
      +        "type": "string"
      +      },
      +      "publicAccess": {
      +        "description": "true if the component is publicly exposed on the internet (not just internally).",
      +        "type": "boolean"
      +      },
      +      "region": {
      +        "description": "Hosting region (e.g. 'eu-west-3', 'cdg1').",
      +        "maxLength": 40,
      +        "type": "string"
      +      },
      +      "slo": {
      +        "additionalProperties": false,
      +        "description": "Service-level objectives (latency, availability).",
      +        "properties": {
      +          "availabilityPct": {
      +            "description": "Target availability, in % (e.g. 99.9).",
      +            "maximum": 100,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "p99LatencyMs": {
      +            "description": "Target or observed p99 latency, in milliseconds.",
      +            "maximum": 60000,
      +            "minimum": 0,
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "technology": {
      +        "description": "Concrete technology/framework (e.g. 'Node.js 22', 'Amazon Aurora PostgreSQL 15.4 Serverless v2').",
      +        "maxLength": 120,
      +        "type": "string"
      +      },
      +      "trustBoundary": {
      +        "description": "Name of the trust zone/security perimeter (e.g. 'DMZ', 'private VPC', 'PCI zone') — components sharing the same trustBoundary can be grouped visually.",
      +        "maxLength": 40,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "archType"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "actor": {
      +        "description": "Actor/role performing this specific task, if different from the lane's default actor.",
      +        "maxLength": 80,
      +        "type": "string"
      +      },
      +      "collapsed": {
      +        "description": "true to visually collapse a subprocess (hides its children on the canvas).",
      +        "type": "boolean"
      +      },
      +      "complianceTags": {
      +        "description": "Regulatory tags that apply to this step (e.g. 'gdpr', 'sox', 'pci', 'hipaa', 'kyc', 'aml', 'iso27001', 'four-eyes').",
      +        "items": {
      +          "maxLength": 20,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "maxItems": 8,
      +        "type": "array"
      +      },
      +      "cost": {
      +        "additionalProperties": false,
      +        "description": "Processing cost per case for this step.",
      +        "properties": {
      +          "note": {
      +            "description": "Free-form note on the cost.",
      +            "maxLength": 120,
      +            "type": "string"
      +          },
      +          "perCaseUsd": {
      +            "description": "Processing cost per case/instance, in USD.",
      +            "maximum": 1000000,
      +            "minimum": 0,
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "perCaseUsd"
      +        ],
      +        "type": "object"
      +      },
      +      "duration": {
      +        "additionalProperties": false,
      +        "description": "Typical processing time of this step.",
      +        "properties": {
      +          "unit": {
      +            "description": "Unit: minutes, hours or days.",
      +            "enum": [
      +              "min",
      +              "h",
      +              "d"
      +            ],
      +            "type": "string"
      +          },
      +          "value": {
      +            "description": "Numeric value of the duration.",
      +            "exclusiveMinimum": 0,
      +            "maximum": 100000,
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "value",
      +          "unit"
      +        ],
      +        "type": "object"
      +      },
      +      "executionPct": {
      +        "description": "% of the process instances that actually go through this step (100 = path always taken).",
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "isBottleneck": {
      +        "description": "true to visually mark this step as an identified bottleneck (problematic duration/SLA).",
      +        "type": "boolean"
      +      },
      +      "laneId": {
      +        "description": "ID of the parent lane (block with processType='lane') to attach this task/event to — kebab-case, as returned by add_swimlane (e.g. 'lane-sales').",
      +        "type": "string"
      +      },
      +      "processType": {
      +        "description": "BPMN-lite role of the block — determines its shape on the canvas: 'task' (rectangle), 'event-start'/'event-end' (start/end circle), 'event-intermediate-timer'/'event-intermediate-error' (intermediate circle), 'gateway-xor'/'gateway-and'/'gateway-or' (decision diamond), 'subprocess' (double-bordered rectangle), 'lane' (swimlane — normally created via add_swimlane, not directly via add_kind_node).",
      +        "enum": [
      +          "task",
      +          "event-start",
      +          "event-end",
      +          "event-intermediate-timer",
      +          "event-intermediate-error",
      +          "gateway-xor",
      +          "gateway-and",
      +          "gateway-or",
      +          "subprocess",
      +          "lane"
      +        ],
      +        "type": "string"
      +      },
      +      "sla": {
      +        "additionalProperties": false,
      +        "description": "Maximum contractual/target delay for this step (compared with duration to detect overruns).",
      +        "properties": {
      +          "unit": {
      +            "description": "Unit: minutes, hours or days.",
      +            "enum": [
      +              "min",
      +              "h",
      +              "d"
      +            ],
      +            "type": "string"
      +          },
      +          "value": {
      +            "description": "Numeric value of the duration.",
      +            "exclusiveMinimum": 0,
      +            "maximum": 100000,
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "value",
      +          "unit"
      +        ],
      +        "type": "object"
      +      },
      +      "swimlaneOrder": {
      +        "description": "Vertical order within the lane (rarely used — otherwise the order of the lanes follows `order`, then the id).",
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "taskType": {
      +        "description": "Type of performer for a task: 'user' (human via the UI), 'service' (system/API), 'manual' (human outside the system, e.g. paper), 'script' (batch automation).",
      +        "enum": [
      +          "user",
      +          "service",
      +          "manual",
      +          "script"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "processType"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "channel": {
      +        "description": "Main channel through which this interaction takes place.",
      +        "enum": [
      +          "web",
      +          "email",
      +          "app",
      +          "phone",
      +          "in-person",
      +          "social",
      +          "sms",
      +          "chat",
      +          "push"
      +        ],
      +        "type": "string"
      +      },
      +      "channels": {
      +        "description": "Multiple channels if the touchpoint is multi-channel (channel alone is enough for a single channel).",
      +        "items": {
      +          "enum": [
      +            "web",
      +            "email",
      +            "app",
      +            "phone",
      +            "in-person",
      +            "social",
      +            "sms",
      +            "chat",
      +            "push"
      +          ],
      +          "type": "string"
      +        },
      +        "maxItems": 8,
      +        "type": "array"
      +      },
      +      "emotion": {
      +        "anyOf": [
      +          {
      +            "const": -2,
      +            "type": "number"
      +          },
      +          {
      +            "const": -1,
      +            "type": "number"
      +          },
      +          {
      +            "const": 0,
      +            "type": "number"
      +          },
      +          {
      +            "const": 1,
      +            "type": "number"
      +          },
      +          {
      +            "const": 2,
      +            "type": "number"
      +          }
      +        ],
      +        "description": "Customer emotional score at this step, from -2 (very negative/frustration) to +2 (very positive/delight), 0 = neutral. Is NOT automatically rendered as a curve on the canvas (see compute_emotion_curve to aggregate it) — a score ≤ -1 typically signals a pain point to document via an associated 'pain' block."
      +      },
      +      "isMomentOfTruth": {
      +        "description": "true to mark a decisive moment that strongly influences the customer's overall perception (visually highlighted).",
      +        "type": "boolean"
      +      },
      +      "journeyType": {
      +        "description": "Role of the block in the journey map: 'phase' (major stage, header column), 'step' (concrete user action), 'touchpoint' (point of contact with a channel/product), 'pain' (pain point/irritant), 'opportunity' (identified improvement lead), 'headline' (free title/context block).",
      +        "enum": [
      +          "phase",
      +          "step",
      +          "touchpoint",
      +          "pain",
      +          "opportunity",
      +          "headline"
      +        ],
      +        "type": "string"
      +      },
      +      "metrics": {
      +        "description": "Figures attached to this step (NPS, rates, duration...).",
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "delta": {
      +              "description": "Change displayed next to the value (e.g. '+5 pts', '-2%').",
      +              "maxLength": 20,
      +              "type": "string"
      +            },
      +            "hint": {
      +              "description": "Explanatory tooltip (source of the data, measurement period...).",
      +              "maxLength": 120,
      +              "type": "string"
      +            },
      +            "label": {
      +              "description": "Short name of the metric (e.g. 'NPS', 'Conversion rate').",
      +              "maxLength": 40,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "trend": {
      +              "description": "Direction of the trend arrow displayed with delta.",
      +              "enum": [
      +                "up",
      +                "down",
      +                "flat"
      +              ],
      +              "type": "string"
      +            },
      +            "value": {
      +              "description": "Displayed value (e.g. '42', '12.3%') — free text, not necessarily numeric.",
      +              "maxLength": 40,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label",
      +            "value"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 6,
      +        "type": "array"
      +      },
      +      "orderInPhase": {
      +        "description": "Horizontal order within the phase (0 = first). Absent = appended on the right.",
      +        "maximum": 1000,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "phaseId": {
      +        "description": "ID of the parent phase (block with journeyType='phase', created via add_journey_phase) — places the block in the right column.",
      +        "type": "string"
      +      },
      +      "quote": {
      +        "additionalProperties": false,
      +        "description": "Customer verbatim illustrating this point of the journey.",
      +        "properties": {
      +          "author": {
      +            "description": "Attribution (e.g. 'B2B customer, 50 employees', first name if known).",
      +            "maxLength": 80,
      +            "type": "string"
      +          },
      +          "text": {
      +            "description": "Verbatim quote from the customer/user.",
      +            "maxLength": 280,
      +            "minLength": 1,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "text"
      +        ],
      +        "type": "object"
      +      },
      +      "severity": {
      +        "description": "Severity of a pain point or priority of an opportunity.",
      +        "enum": [
      +          "low",
      +          "medium",
      +          "high"
      +        ],
      +        "type": "string"
      +      },
      +      "swimlane": {
      +        "description": "Horizontal lane (service blueprint model): 'customer' (actions visible to the customer), 'frontstage' (customer-visible interactions on the company side), 'backstage' (internal operations invisible to the customer), 'support' (support systems/processes).",
      +        "enum": [
      +          "customer",
      +          "frontstage",
      +          "backstage",
      +          "support"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "journeyType"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "oneOf": [
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "captableType": {
      +            "const": "holder",
      +            "description": "Fixed discriminant — identifies this block as a shareholder/holder of securities (as opposed to a round).",
      +            "type": "string"
      +          },
      +          "holderType": {
      +            "description": "Category of holder: 'founder' (co-founder), 'employee' (employee with BSPCE/options), 'investor' (VC/business angel), 'pool' (unallocated ESOP reserve), 'entity' (legal entity, holding, SPV).",
      +            "enum": [
      +              "founder",
      +              "employee",
      +              "investor",
      +              "pool",
      +              "entity"
      +            ],
      +            "type": "string"
      +          },
      +          "isConcentrated": {
      +            "description": "true to mark this holder as a concentration signal (used by validate_captable).",
      +            "type": "boolean"
      +          },
      +          "liquidationPreference": {
      +            "additionalProperties": false,
      +            "description": "Liquidation preference that applies (typical for preferred).",
      +            "properties": {
      +              "dividendRatePct": {
      +                "description": "Cumulative dividend rate, in % per year (e.g. 8 for 8%/year, NVCA default). Accrues at SIMPLE interest on the amount invested between the round date and the exit date, added on top of the preference. Omit for no dividend.",
      +                "maximum": 100,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "multiplier": {
      +                "description": "Liquidation preference multiple (e.g. 1 = 1×, 2 = 2×) — amount recovered first = multiplier × amount invested.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 10,
      +                "type": "number"
      +              },
      +              "participating": {
      +                "description": "true = \"participating\" preferred (receives the liquidation preference THEN also participates in the residual pro rata with the common) ; false = \"non-participating\" (receives the max of the preference AND the pro rata conversion into common, and not both).",
      +                "type": "boolean"
      +              }
      +            },
      +            "required": [
      +              "multiplier",
      +              "participating"
      +            ],
      +            "type": "object"
      +          },
      +          "pricePerShare": {
      +            "description": "Price paid per share at issuance — absent for an unconverted SAFE.",
      +            "maximum": 1000000000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "safeTerms": {
      +            "additionalProperties": false,
      +            "description": "Terms of the SAFE — required if securityType='safe', ignored otherwise.",
      +            "properties": {
      +              "capBasis": {
      +                "description": "Basis on which valuationCap applies. 'post-money' = YC SAFE v2 convention (the most common since 2018).",
      +                "enum": [
      +                  "post-money",
      +                  "pre-money"
      +                ],
      +                "type": "string"
      +              },
      +              "discountPct": {
      +                "description": "Discount in % on the price per share of the next priced round (e.g. 20 for a 20% discount).",
      +                "maximum": 100,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "investmentUsd": {
      +                "description": "Amount invested through this SAFE, in USD (or the project currency).",
      +                "maximum": 1000000000000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "mfn": {
      +                "description": "Most Favored Nation — true if this SAFE automatically benefits from the more favorable terms granted to a later SAFE.",
      +                "type": "boolean"
      +              },
      +              "valuationCap": {
      +                "description": "Valuation cap of the SAFE — above it, the SAFE converts as if the valuation were capped at this amount.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 1000000000000,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "securityRound": {
      +            "description": "ID of the round (block with captableType='round') in which this security was issued — absent = founding issuance (t=0). UUID or kebab-case, like the rest of the block ids.",
      +            "type": "string"
      +          },
      +          "securityType": {
      +            "description": "Type of security held: 'common' (common stock, typically founders), 'preferred' (preferred stock, typically priced-round investors), 'safe' (unconverted SAFE — see safeTerms), 'convertible' (convertible note), 'option' (unexercised stock options/BSPCE).",
      +            "enum": [
      +              "common",
      +              "preferred",
      +              "safe",
      +              "convertible",
      +              "option"
      +            ],
      +            "type": "string"
      +          },
      +          "shares": {
      +            "description": "Number of shares held (integer or decimal depending on the granularity of the cap table).",
      +            "maximum": 1000000000000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "vestingSchedule": {
      +            "additionalProperties": false,
      +            "description": "Vesting schedule that applies to these shares (typical for founder/employee).",
      +            "properties": {
      +              "cliffMonths": {
      +                "description": "Cliff duration in months (period before which 0 shares are vested, e.g. 12).",
      +                "maximum": 120,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "startDate": {
      +                "description": "Vesting start date (YYYY-MM-DD).",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "totalMonths": {
      +                "description": "Total vesting duration in months (e.g. 48 for a standard 4-year vesting).",
      +                "maximum": 240,
      +                "minimum": 1,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "startDate",
      +              "cliffMonths",
      +              "totalMonths"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "captableType",
      +          "holderType",
      +          "securityType",
      +          "shares"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "amountRaised": {
      +            "description": "Total amount raised in this round.",
      +            "maximum": 1000000000000000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "captableType": {
      +            "const": "round",
      +            "description": "Fixed discriminant — identifies this block as a funding round (as opposed to a holder).",
      +            "type": "string"
      +          },
      +          "date": {
      +            "description": "Closing date of the round (YYYY-MM-DD).",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          },
      +          "esopRefreshPct": {
      +            "description": "% of ESOP pool refresh carried out on the occasion of this round.",
      +            "maximum": 100,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "name": {
      +            "description": "Name of the round (e.g. 'Seed', 'Series A', 'Bridge').",
      +            "maxLength": 80,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "preMoneyValuation": {
      +            "description": "Pre-money valuation of the round, in the project currency.",
      +            "maximum": 1000000000000000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "riskTags": {
      +            "description": "Risk signals associated with this round: 'down-round', 'concentration', 'underwater-options', 'anti-dilution'.",
      +            "items": {
      +              "enum": [
      +                "down-round",
      +                "concentration",
      +                "underwater-options",
      +                "anti-dilution"
      +              ],
      +              "type": "string"
      +            },
      +            "maxItems": 8,
      +            "type": "array"
      +          },
      +          "termSheetNote": {
      +            "description": "Free-form note on the negotiated terms (special clauses, board seat, pro-rata rights...).",
      +            "maxLength": 160,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "captableType",
      +          "name",
      +          "date",
      +          "preMoneyValuation",
      +          "amountRaised"
      +        ],
      +        "type": "object"
      +      }
      +    ]
      +  }
      +]
    • changedInput schema / properties / metadata / description
      Previous value: -"Métadonnées spécifiques au kind — la shape dépend de la valeur de `kind` ci-dessus : arch → { archType (obligatoire: service|datastore|queue|gateway|external|lambda|batch|network|cdn|cache), technology?, cloudProvider?, region?, cost?, slo?, dataClassification?, ... } ; process → { processType (obligatoire: task|event-start|event-end|gateway-xor|gateway-and|gateway-or|subprocess|lane), laneId?, taskType?, duration?, sla?, isBottleneck?, complianceTags?, ... } ; journey → { journeyType (obligatoire: phase|step|touchpoint|pain|opportunity|headline), phaseId?, swimlane?, emotion? (-2..+2), isMomentOfTruth?, ... } ; captable → { captableType (obligatoire: 'holder'|'round') puis soit holderType/securityType/shares/securityRound/... soit name/date/preMoneyValuation/amountRaised/... }. Chaque champ est documenté individuellement dans son propre schéma (voir archMetadataSchema / processMetadataSchema / journeyMetadataSchema / captableMetadataSchema côté serveur) — cette description reste le seul point d'entrée visible pour un client MCP externe."New value: +"Kind-specific metadata — the shape depends on the value of `kind` above: arch → { archType (required: service|datastore|queue|gateway|external|lambda|batch|network|cdn|cache), technology?, cloudProvider?, region?, cost?, slo?, dataClassification?, ... } ; process → { processType (required: task|event-start|event-end|gateway-xor|gateway-and|gateway-or|subprocess|lane), laneId?, taskType?, duration?, sla?, isBottleneck?, complianceTags?, ... } ; journey → { journeyType (required: phase|step|touchpoint|pain|opportunity|headline), phaseId?, swimlane?, emotion? (-2..+2), isMomentOfTruth?, ... } ; captable → { captableType (required: 'holder'|'round') then either holderType/securityType/shares/securityRound/... or name/date/preMoneyValuation/amountRaised/... }. Each field is documented individually in its own schema (see archMetadataSchema / processMetadataSchema / journeyMetadataSchema / captableMetadataSchema server-side) — this description remains the only entry point visible to an external MCP client."
    • changedInput schema / properties / name / description
      Previous value: -"Nom court affiché sur le nœud."New value: +"Short name displayed on the node."
    • changedInput schema / properties / parentId / description
      Previous value: -"ID du parent (container ou network)."New value: +"ID of the parent (container or network)."
    • changedInput schema / properties / width / description
      Previous value: -"Largeur en pixels. Absent = largeur par défaut du kind."New value: +"Width in pixels. Absent = default width of the kind."
    • changedInput schema / properties / x / description
      Previous value: -"Position X en pixels (React Flow). Omis (avec y/width/height), le champ laisse resolveAutoPosition placer le nœud automatiquement selon son kind (ex: une task process atterrit dans sa lane, un step journey dans sa case (phase, swimlane))."New value: +"X position in pixels (React Flow). When omitted (with y/width/height), the field lets resolveAutoPosition place the node automatically according to its kind (e.g. a process task lands in its lane, a journey step in its (phase, swimlane) cell)."
    • changedInput schema / properties / y / description
      Previous value: -"Position Y en pixels (React Flow). Voir x — absent = auto-layout."New value: +"Y position in pixels (React Flow). See x — absent = auto-layout."
  2. Changed4 schema fields changed
    • changedInput schema / properties / kind / description
      Previous value: -"Type de diagramme : arch | process | journey | captable UNIQUEMENT. Pour 'org' utilise add_cell, pour 'entity' utilise add_entity. Doit matcher le primary_kind du projet sauf si l'utilisateur demande explicitement de mixer."New value: +"Type de diagramme : arch | process | journey | captable UNIQUEMENT ('org' relève d'add_cell, 'entity' d'add_entity). Doit matcher le primary_kind du projet sauf si l'utilisateur demande explicitement de mixer."
    • changedInput schema / properties / metadata / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "archType": {
      -        "description": "Nature du composant d'architecture — détermine l'icône et la couleur par défaut du nœud. 'service' = appli/API, 'datastore' = DB/storage, 'queue' = message broker, 'gateway' = API gateway/LB, 'external' = dépendance tierce hors du périmètre, 'lambda' = fonction serverless, 'batch' = job/cron, 'network' = VPC/subnet/segment réseau, 'cdn' = edge/CDN, 'cache' = cache mémoire (Redis, Memcached...).",
      -        "enum": [
      -          "service",
      -          "datastore",
      -          "queue",
      -          "gateway",
      -          "external",
      -          "lambda",
      -          "batch",
      -          "network",
      -          "cdn",
      -          "cache"
      -        ],
      -        "type": "string"
      -      },
      -      "capacity": {
      -        "description": "Dimensionnement libre (ex: '4 vCPU / 8GB', 'db.r6g.large', 'auto-scale 2-10 pods').",
      -        "maxLength": 120,
      -        "type": "string"
      -      },
      -      "cloudProvider": {
      -        "description": "Fournisseur cloud hébergeant ce composant.",
      -        "enum": [
      -          "aws",
      -          "gcp",
      -          "azure",
      -          "on-prem"
      -        ],
      -        "type": "string"
      -      },
      -      "cost": {
      -        "additionalProperties": false,
      -        "description": "Coût mensuel estimé — affiché sur le nœud si présent.",
      -        "properties": {
      -          "monthlyUsd": {
      -            "description": "Coût mensuel estimé du composant, en USD.",
      -            "maximum": 1000000000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "note": {
      -            "description": "Précision libre sur le coût (ex: 'tier réservé 1 an', 'estimation à 10k req/j').",
      -            "maxLength": 120,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "monthlyUsd"
      -        ],
      -        "type": "object"
      -      },
      -      "dataClassification": {
      -        "description": "Sensibilité des données traitées/stockées par ce composant : 'public' | 'internal' | 'confidential' | 'pii' | 'secret'. Utilisée pour mettre en évidence les composants à surveiller (ex: tout ce qui touche 'pii').",
      -        "enum": [
      -          "public",
      -          "internal",
      -          "confidential",
      -          "pii",
      -          "secret"
      -        ],
      -        "type": "string"
      -      },
      -      "providerLogo": {
      -        "description": "Logo de service tiers à afficher sur le nœud (ex: 'aws', 'stripe', 'supabase') — purement visuel, indépendant de cloudProvider.",
      -        "enum": [
      -          "aws",
      -          "gcp",
      -          "azure",
      -          "cloudflare",
      -          "vercel",
      -          "fly",
      -          "openai",
      -          "anthropic",
      -          "mistral",
      -          "cohere",
      -          "huggingface",
      -          "replicate",
      -          "pinecone",
      -          "qdrant",
      -          "weaviate",
      -          "chroma",
      -          "postgres",
      -          "mysql",
      -          "mongodb",
      -          "redis",
      -          "snowflake",
      -          "bigquery",
      -          "clickhouse",
      -          "kafka",
      -          "sqs",
      -          "pubsub",
      -          "rabbitmq",
      -          "stripe",
      -          "twilio",
      -          "sendgrid",
      -          "resend",
      -          "auth0",
      -          "clerk",
      -          "supabase",
      -          "datadog",
      -          "sentry",
      -          "segment",
      -          "mixpanel",
      -          "github",
      -          "linear",
      -          "notion",
      -          "slack"
      -        ],
      -        "type": "string"
      -      },
      -      "publicAccess": {
      -        "description": "true si le composant est exposé publiquement sur internet (pas seulement en interne).",
      -        "type": "boolean"
      -      },
      -      "region": {
      -        "description": "Région d'hébergement (ex: 'eu-west-3', 'cdg1').",
      -        "maxLength": 40,
      -        "type": "string"
      -      },
      -      "slo": {
      -        "additionalProperties": false,
      -        "description": "Objectifs de niveau de service (latence, disponibilité).",
      -        "properties": {
      -          "availabilityPct": {
      -            "description": "Disponibilité cible, en % (ex: 99.9).",
      -            "maximum": 100,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "p99LatencyMs": {
      -            "description": "Latence p99 cible ou observée, en millisecondes.",
      -            "maximum": 60000,
      -            "minimum": 0,
      -            "type": "number"
      -          }
      -        },
      -        "type": "object"
      -      },
      -      "technology": {
      -        "description": "Techno/framework concret (ex: 'Node.js 22', 'Amazon Aurora PostgreSQL 15.4 Serverless v2').",
      -        "maxLength": 120,
      -        "type": "string"
      -      },
      -      "trustBoundary": {
      -        "description": "Nom de la zone de confiance/périmètre de sécurité (ex: 'DMZ', 'VPC privé', 'zone PCI') — les composants partageant le même trustBoundary sont visuellement groupables.",
      -        "maxLength": 40,
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "archType"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "actor": {
      -        "description": "Acteur/rôle exécutant cette tâche précise, si différent de l'acteur par défaut de la lane.",
      -        "maxLength": 80,
      -        "type": "string"
      -      },
      -      "collapsed": {
      -        "description": "true pour replier visuellement un subprocess (masque ses enfants sur le canvas).",
      -        "type": "boolean"
      -      },
      -      "complianceTags": {
      -        "description": "Tags réglementaires applicables à cette étape (ex: 'gdpr', 'sox', 'pci', 'hipaa', 'kyc', 'aml', 'iso27001', 'four-eyes').",
      -        "items": {
      -          "maxLength": 20,
      -          "minLength": 1,
      -          "type": "string"
      -        },
      -        "maxItems": 8,
      -        "type": "array"
      -      },
      -      "cost": {
      -        "additionalProperties": false,
      -        "description": "Coût de traitement par dossier pour cette étape.",
      -        "properties": {
      -          "note": {
      -            "description": "Précision libre sur le coût.",
      -            "maxLength": 120,
      -            "type": "string"
      -          },
      -          "perCaseUsd": {
      -            "description": "Coût de traitement par dossier/instance, en USD.",
      -            "maximum": 1000000,
      -            "minimum": 0,
      -            "type": "number"
      -          }
      -        },
      -        "required": [
      -          "perCaseUsd"
      -        ],
      -        "type": "object"
      -      },
      -      "duration": {
      -        "additionalProperties": false,
      -        "description": "Durée de traitement typique de cette étape.",
      -        "properties": {
      -          "unit": {
      -            "description": "Unité: minutes, heures ou jours.",
      -            "enum": [
      -              "min",
      -              "h",
      -              "d"
      -            ],
      -            "type": "string"
      -          },
      -          "value": {
      -            "description": "Valeur numérique de la durée.",
      -            "exclusiveMinimum": 0,
      -            "maximum": 100000,
      -            "type": "number"
      -          }
      -        },
      -        "required": [
      -          "value",
      -          "unit"
      -        ],
      -        "type": "object"
      -      },
      -      "executionPct": {
      -        "description": "% des instances du process qui passent réellement par cette étape (100 = chemin toujours emprunté).",
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "number"
      -      },
      -      "isBottleneck": {
      -        "description": "true pour marquer visuellement cette étape comme goulot d’étranglement identifié (durée/SLA problématique).",
      -        "type": "boolean"
      -      },
      -      "laneId": {
      -        "description": "ID de la lane parente (cellule processType='lane') à laquelle rattacher cette task/event — kebab-case, comme retourné par add_swimlane (ex: 'lane-sales').",
      -        "type": "string"
      -      },
      -      "processType": {
      -        "description": "Rôle BPMN-lite de la cellule — détermine sa forme sur le canvas : 'task' (rectangle), 'event-start'/'event-end' (cercle début/fin), 'event-intermediate-timer'/'event-intermediate-error' (cercle intermédiaire), 'gateway-xor'/'gateway-and'/'gateway-or' (losange de décision), 'subprocess' (rectangle double-bordure), 'lane' (couloir — normalement créé via add_swimlane, pas via add_kind_node directement).",
      -        "enum": [
      -          "task",
      -          "event-start",
      -          "event-end",
      -          "event-intermediate-timer",
      -          "event-intermediate-error",
      -          "gateway-xor",
      -          "gateway-and",
      -          "gateway-or",
      -          "subprocess",
      -          "lane"
      -        ],
      -        "type": "string"
      -      },
      -      "sla": {
      -        "additionalProperties": false,
      -        "description": "Délai maximum contractuel/cible pour cette étape (comparé à duration pour détecter les dépassements).",
      -        "properties": {
      -          "unit": {
      -            "description": "Unité: minutes, heures ou jours.",
      -            "enum": [
      -              "min",
      -              "h",
      -              "d"
      -            ],
      -            "type": "string"
      -          },
      -          "value": {
      -            "description": "Valeur numérique de la durée.",
      -            "exclusiveMinimum": 0,
      -            "maximum": 100000,
      -            "type": "number"
      -          }
      -        },
      -        "required": [
      -          "value",
      -          "unit"
      -        ],
      -        "type": "object"
      -      },
      -      "swimlaneOrder": {
      -        "description": "Ordre vertical au sein de la lane (rarement utilisé — préférer order via auto_layout_process).",
      -        "maximum": 100,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "taskType": {
      -        "description": "Type d'exécutant pour une task : 'user' (humain via UI), 'service' (système/API), 'manual' (humain hors-système, ex: papier), 'script' (automatisation batch).",
      -        "enum": [
      -          "user",
      -          "service",
      -          "manual",
      -          "script"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "processType"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "additionalProperties": false,
      -    "properties": {
      -      "channel": {
      -        "description": "Canal principal via lequel cette interaction a lieu.",
      -        "enum": [
      -          "web",
      -          "email",
      -          "app",
      -          "phone",
      -          "in-person",
      -          "social",
      -          "sms",
      -          "chat",
      -          "push"
      -        ],
      -        "type": "string"
      -      },
      -      "channels": {
      -        "description": "Canaux multiples si le touchpoint est multi-canal (préférer channel seul si un canal unique suffit).",
      -        "items": {
      -          "enum": [
      -            "web",
      -            "email",
      -            "app",
      -            "phone",
      -            "in-person",
      -            "social",
      -            "sms",
      -            "chat",
      -            "push"
      -          ],
      -          "type": "string"
      -        },
      -        "maxItems": 8,
      -        "type": "array"
      -      },
      -      "emotion": {
      -        "anyOf": [
      -          {
      -            "const": -2,
      -            "type": "number"
      -          },
      -          {
      -            "const": -1,
      -            "type": "number"
      -          },
      -          {
      -            "const": 0,
      -            "type": "number"
      -          },
      -          {
      -            "const": 1,
      -            "type": "number"
      -          },
      -          {
      -            "const": 2,
      -            "type": "number"
      -          }
      -        ],
      -        "description": "Score émotionnel du client à cette étape, de -2 (très négatif/frustration) à +2 (très positif/enchantement), 0 = neutre. N'est PAS rendu comme courbe sur le canvas automatiquement (voir compute_emotion_curve pour l'agréger) — un score ≤ -1 signale typiquement un point de friction à documenter via une cellule 'pain' associée."
      -      },
      -      "isMomentOfTruth": {
      -        "description": "true pour marquer un instant décisif qui influence fortement la perception globale du client (mis en évidence visuellement).",
      -        "type": "boolean"
      -      },
      -      "journeyType": {
      -        "description": "Rôle de la cellule dans la carte de parcours : 'phase' (grande étape, colonne d'en-tête), 'step' (action concrète de l'utilisateur), 'touchpoint' (point de contact avec un canal/produit), 'pain' (point de friction/irritant), 'opportunity' (piste d'amélioration identifiée), 'headline' (bloc de titre/contexte libre).",
      -        "enum": [
      -          "phase",
      -          "step",
      -          "touchpoint",
      -          "pain",
      -          "opportunity",
      -          "headline"
      -        ],
      -        "type": "string"
      -      },
      -      "metrics": {
      -        "description": "Indicateurs chiffrés rattachés à cette étape (NPS, taux, durée...).",
      -        "items": {
      -          "additionalProperties": false,
      -          "properties": {
      -            "delta": {
      -              "description": "Variation affichée à côté de la valeur (ex: '+5 pts', '-2%').",
      -              "maxLength": 20,
      -              "type": "string"
      -            },
      -            "hint": {
      -              "description": "Info-bulle explicative (source de la donnée, période de mesure...).",
      -              "maxLength": 120,
      -              "type": "string"
      -            },
      -            "label": {
      -              "description": "Nom court de la métrique (ex: 'NPS', 'Taux de conversion').",
      -              "maxLength": 40,
      -              "minLength": 1,
      -              "type": "string"
      -            },
      -            "trend": {
      -              "description": "Sens de la flèche de tendance affichée avec delta.",
      -              "enum": [
      -                "up",
      -                "down",
      -                "flat"
      -              ],
      -              "type": "string"
      -            },
      -            "value": {
      -              "description": "Valeur affichée (ex: '42', '12.3%') — texte libre, pas forcément numérique.",
      -              "maxLength": 40,
      -              "minLength": 1,
      -              "type": "string"
      -            }
      -          },
      -          "required": [
      -            "label",
      -            "value"
      -          ],
      -          "type": "object"
      -        },
      -        "maxItems": 6,
      -        "type": "array"
      -      },
      -      "orderInPhase": {
      -        "description": "Ordre horizontal au sein de la phase (0 = en premier). Absent = append à droite.",
      -        "maximum": 1000,
      -        "minimum": 0,
      -        "type": "integer"
      -      },
      -      "phaseId": {
      -        "description": "ID de la phase parente (cellule journeyType='phase', créée via add_journey_phase) — positionne la cellule dans la bonne colonne.",
      -        "type": "string"
      -      },
      -      "quote": {
      -        "additionalProperties": false,
      -        "description": "Verbatim client illustrant ce point du parcours.",
      -        "properties": {
      -          "author": {
      -            "description": "Attribution (ex: 'Client B2B, 50 employés', prénom si connu).",
      -            "maxLength": 80,
      -            "type": "string"
      -          },
      -          "text": {
      -            "description": "Citation verbatim du client/utilisateur.",
      -            "maxLength": 280,
      -            "minLength": 1,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "text"
      -        ],
      -        "type": "object"
      -      },
      -      "severity": {
      -        "description": "Gravité d'un pain point ou priorité d'une opportunity.",
      -        "enum": [
      -          "low",
      -          "medium",
      -          "high"
      -        ],
      -        "type": "string"
      -      },
      -      "swimlane": {
      -        "description": "Couloir horizontal (modèle service blueprint) : 'customer' (actions visibles du client), 'frontstage' (interactions client-visibles côté entreprise), 'backstage' (opérations internes invisibles du client), 'support' (systèmes/process support).",
      -        "enum": [
      -          "customer",
      -          "frontstage",
      -          "backstage",
      -          "support"
      -        ],
      -        "type": "string"
      -      }
      -    },
      -    "required": [
      -      "journeyType"
      -    ],
      -    "type": "object"
      -  },
      -  {
      -    "oneOf": [
      -      {
      -        "additionalProperties": false,
      -        "properties": {
      -          "captableType": {
      -            "const": "holder",
      -            "description": "Discriminant fixe — identifie cette cellule comme un actionnaire/détenteur de titres (par opposition à un round).",
      -            "type": "string"
      -          },
      -          "holderType": {
      -            "description": "Catégorie de détenteur : 'founder' (co-fondateur), 'employee' (salarié avec BSPCE/options), 'investor' (VC/business angel), 'pool' (réserve ESOP non-allouée), 'entity' (personne morale, holding, SPV).",
      -            "enum": [
      -              "founder",
      -              "employee",
      -              "investor",
      -              "pool",
      -              "entity"
      -            ],
      -            "type": "string"
      -          },
      -          "isConcentrated": {
      -            "description": "true pour marquer ce holder comme signal de concentration (utilisé par validate_captable).",
      -            "type": "boolean"
      -          },
      -          "liquidationPreference": {
      -            "additionalProperties": false,
      -            "description": "Préférence de liquidation applicable (typique pour preferred).",
      -            "properties": {
      -              "dividendRatePct": {
      -                "description": "Taux de dividende cumulatif, en % annuel (ex: 8 pour 8%/an, défaut NVCA). Court en intérêt SIMPLE sur le montant investi entre la date du round et la date de sortie, ajouté par-dessus la préférence. Omettre pour aucun dividende.",
      -                "maximum": 100,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "multiplier": {
      -                "description": "Multiple de préférence de liquidation (ex: 1 = 1×, 2 = 2×) — montant récupéré en priorité = multiplier × montant investi.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 10,
      -                "type": "number"
      -              },
      -              "participating": {
      -                "description": "true = preferred \"participating\" (touche la préférence de liquidation PUIS participe aussi au pro-rata résiduel avec les common) ; false = \"non-participating\" (touche le max entre la préférence ET la conversion pro-rata en common, jamais les deux).",
      -                "type": "boolean"
      -              }
      -            },
      -            "required": [
      -              "multiplier",
      -              "participating"
      -            ],
      -            "type": "object"
      -          },
      -          "pricePerShare": {
      -            "description": "Prix payé par action lors de l'émission — absent pour un SAFE non converti.",
      -            "maximum": 1000000000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "safeTerms": {
      -            "additionalProperties": false,
      -            "description": "Termes du SAFE — requis si securityType='safe', ignoré sinon.",
      -            "properties": {
      -              "capBasis": {
      -                "description": "Base sur laquelle s'applique valuationCap. 'post-money' = convention YC SAFE v2 (la plus courante depuis 2018).",
      -                "enum": [
      -                  "post-money",
      -                  "pre-money"
      -                ],
      -                "type": "string"
      -              },
      -              "discountPct": {
      -                "description": "Remise en % sur le prix par action du prochain priced round (ex: 20 pour 20% de discount).",
      -                "maximum": 100,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "investmentUsd": {
      -                "description": "Montant investi via ce SAFE, en USD (ou monnaie du projet).",
      -                "maximum": 1000000000000,
      -                "minimum": 0,
      -                "type": "number"
      -              },
      -              "mfn": {
      -                "description": "Most Favored Nation — true si ce SAFE bénéficie automatiquement des termes plus favorables accordés à un SAFE ultérieur.",
      -                "type": "boolean"
      -              },
      -              "valuationCap": {
      -                "description": "Plafond de valorisation du SAFE — au-delà, le SAFE convertit comme si la valorisation était plafonnée à ce montant.",
      -                "exclusiveMinimum": 0,
      -                "maximum": 1000000000000,
      -                "type": "number"
      -              }
      -            },
      -            "type": "object"
      -          },
      -          "securityRound": {
      -            "description": "ID du round (cellule captableType='round') dans lequel ce titre a été émis — absent = émission fondatrice (t=0). UUID ou kebab-case, comme le reste des ids de cellule.",
      -            "type": "string"
      -          },
      -          "securityType": {
      -            "description": "Type de titre détenu : 'common' (actions ordinaires, typiquement fondateurs), 'preferred' (actions de préférence, typiquement investisseurs priced round), 'safe' (SAFE non converti — voir safeTerms), 'convertible' (obligation convertible), 'option' (stock-options/BSPCE non exercées).",
      -            "enum": [
      -              "common",
      -              "preferred",
      -              "safe",
      -              "convertible",
      -              "option"
      -            ],
      -            "type": "string"
      -          },
      -          "shares": {
      -            "description": "Nombre de parts/actions détenues (entier ou décimal selon la granularité du cap table).",
      -            "maximum": 1000000000000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "vestingSchedule": {
      -            "additionalProperties": false,
      -            "description": "Calendrier de vesting applicable à ces parts (typique pour founder/employee).",
      -            "properties": {
      -              "cliffMonths": {
      -                "description": "Durée du cliff en mois (période avant laquelle 0 part n'est acquise, ex: 12).",
      -                "maximum": 120,
      -                "minimum": 0,
      -                "type": "integer"
      -              },
      -              "startDate": {
      -                "description": "Date de début du vesting (YYYY-MM-DD).",
      -                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -                "type": "string"
      -              },
      -              "totalMonths": {
      -                "description": "Durée totale du vesting en mois (ex: 48 pour un vesting standard 4 ans).",
      -                "maximum": 240,
      -                "minimum": 1,
      -                "type": "integer"
      -              }
      -            },
      -            "required": [
      -              "startDate",
      -              "cliffMonths",
      -              "totalMonths"
      -            ],
      -            "type": "object"
      -          }
      -        },
      -        "required": [
      -          "captableType",
      -          "holderType",
      -          "securityType",
      -          "shares"
      -        ],
      -        "type": "object"
      -      },
      -      {
      -        "additionalProperties": false,
      -        "properties": {
      -          "amountRaised": {
      -            "description": "Montant total levé lors de ce round.",
      -            "maximum": 1000000000000000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "captableType": {
      -            "const": "round",
      -            "description": "Discriminant fixe — identifie cette cellule comme un tour de financement (par opposition à un holder).",
      -            "type": "string"
      -          },
      -          "date": {
      -            "description": "Date de closing du round (YYYY-MM-DD).",
      -            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      -            "type": "string"
      -          },
      -          "esopRefreshPct": {
      -            "description": "% de refresh du pool ESOP effectué à l'occasion de ce round.",
      -            "maximum": 100,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "name": {
      -            "description": "Nom du round (ex: 'Seed', 'Series A', 'Bridge').",
      -            "maxLength": 80,
      -            "minLength": 1,
      -            "type": "string"
      -          },
      -          "preMoneyValuation": {
      -            "description": "Valorisation pré-money du round, en monnaie du projet.",
      -            "maximum": 1000000000000000,
      -            "minimum": 0,
      -            "type": "number"
      -          },
      -          "riskTags": {
      -            "description": "Signaux de risque associés à ce round : 'down-round', 'concentration', 'underwater-options', 'anti-dilution'.",
      -            "items": {
      -              "enum": [
      -                "down-round",
      -                "concentration",
      -                "underwater-options",
      -                "anti-dilution"
      -              ],
      -              "type": "string"
      -            },
      -            "maxItems": 8,
      -            "type": "array"
      -          },
      -          "termSheetNote": {
      -            "description": "Note libre sur les conditions négociées (clauses particulières, board seat, pro-rata rights...).",
      -            "maxLength": 160,
      -            "type": "string"
      -          }
      -        },
      -        "required": [
      -          "captableType",
      -          "name",
      -          "date",
      -          "preMoneyValuation",
      -          "amountRaised"
      -        ],
      -        "type": "object"
      -      }
      -    ]
      -  }
      -]New value: +[
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "archType": {
      +        "description": "Nature du composant d'architecture — détermine l'icône et la couleur par défaut du nœud. 'service' = appli/API, 'datastore' = DB/storage, 'queue' = message broker, 'gateway' = API gateway/LB, 'external' = dépendance tierce hors du périmètre, 'lambda' = fonction serverless, 'batch' = job/cron, 'network' = VPC/subnet/segment réseau, 'cdn' = edge/CDN, 'cache' = cache mémoire (Redis, Memcached...).",
      +        "enum": [
      +          "service",
      +          "datastore",
      +          "queue",
      +          "gateway",
      +          "external",
      +          "lambda",
      +          "batch",
      +          "network",
      +          "cdn",
      +          "cache"
      +        ],
      +        "type": "string"
      +      },
      +      "capacity": {
      +        "description": "Dimensionnement libre (ex: '4 vCPU / 8GB', 'db.r6g.large', 'auto-scale 2-10 pods').",
      +        "maxLength": 120,
      +        "type": "string"
      +      },
      +      "cloudProvider": {
      +        "description": "Fournisseur cloud hébergeant ce composant.",
      +        "enum": [
      +          "aws",
      +          "gcp",
      +          "azure",
      +          "on-prem"
      +        ],
      +        "type": "string"
      +      },
      +      "cost": {
      +        "additionalProperties": false,
      +        "description": "Coût mensuel estimé — affiché sur le nœud si présent.",
      +        "properties": {
      +          "monthlyUsd": {
      +            "description": "Coût mensuel estimé du composant, en USD.",
      +            "maximum": 1000000000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "note": {
      +            "description": "Précision libre sur le coût (ex: 'tier réservé 1 an', 'estimation à 10k req/j').",
      +            "maxLength": 120,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "monthlyUsd"
      +        ],
      +        "type": "object"
      +      },
      +      "dataClassification": {
      +        "description": "Sensibilité des données traitées/stockées par ce composant : 'public' | 'internal' | 'confidential' | 'pii' | 'secret'. Utilisée pour mettre en évidence les composants à surveiller (ex: tout ce qui touche 'pii').",
      +        "enum": [
      +          "public",
      +          "internal",
      +          "confidential",
      +          "pii",
      +          "secret"
      +        ],
      +        "type": "string"
      +      },
      +      "providerLogo": {
      +        "description": "Logo de service tiers à afficher sur le nœud (ex: 'aws', 'stripe', 'supabase') — purement visuel, indépendant de cloudProvider.",
      +        "enum": [
      +          "aws",
      +          "gcp",
      +          "azure",
      +          "cloudflare",
      +          "vercel",
      +          "fly",
      +          "openai",
      +          "anthropic",
      +          "mistral",
      +          "cohere",
      +          "huggingface",
      +          "replicate",
      +          "pinecone",
      +          "qdrant",
      +          "weaviate",
      +          "chroma",
      +          "postgres",
      +          "mysql",
      +          "mongodb",
      +          "redis",
      +          "snowflake",
      +          "bigquery",
      +          "clickhouse",
      +          "kafka",
      +          "sqs",
      +          "pubsub",
      +          "rabbitmq",
      +          "stripe",
      +          "twilio",
      +          "sendgrid",
      +          "resend",
      +          "auth0",
      +          "clerk",
      +          "supabase",
      +          "datadog",
      +          "sentry",
      +          "segment",
      +          "mixpanel",
      +          "github",
      +          "linear",
      +          "notion",
      +          "slack"
      +        ],
      +        "type": "string"
      +      },
      +      "publicAccess": {
      +        "description": "true si le composant est exposé publiquement sur internet (pas seulement en interne).",
      +        "type": "boolean"
      +      },
      +      "region": {
      +        "description": "Région d'hébergement (ex: 'eu-west-3', 'cdg1').",
      +        "maxLength": 40,
      +        "type": "string"
      +      },
      +      "slo": {
      +        "additionalProperties": false,
      +        "description": "Objectifs de niveau de service (latence, disponibilité).",
      +        "properties": {
      +          "availabilityPct": {
      +            "description": "Disponibilité cible, en % (ex: 99.9).",
      +            "maximum": 100,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "p99LatencyMs": {
      +            "description": "Latence p99 cible ou observée, en millisecondes.",
      +            "maximum": 60000,
      +            "minimum": 0,
      +            "type": "number"
      +          }
      +        },
      +        "type": "object"
      +      },
      +      "technology": {
      +        "description": "Techno/framework concret (ex: 'Node.js 22', 'Amazon Aurora PostgreSQL 15.4 Serverless v2').",
      +        "maxLength": 120,
      +        "type": "string"
      +      },
      +      "trustBoundary": {
      +        "description": "Nom de la zone de confiance/périmètre de sécurité (ex: 'DMZ', 'VPC privé', 'zone PCI') — les composants partageant le même trustBoundary sont visuellement groupables.",
      +        "maxLength": 40,
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "archType"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "actor": {
      +        "description": "Acteur/rôle exécutant cette tâche précise, si différent de l'acteur par défaut de la lane.",
      +        "maxLength": 80,
      +        "type": "string"
      +      },
      +      "collapsed": {
      +        "description": "true pour replier visuellement un subprocess (masque ses enfants sur le canvas).",
      +        "type": "boolean"
      +      },
      +      "complianceTags": {
      +        "description": "Tags réglementaires applicables à cette étape (ex: 'gdpr', 'sox', 'pci', 'hipaa', 'kyc', 'aml', 'iso27001', 'four-eyes').",
      +        "items": {
      +          "maxLength": 20,
      +          "minLength": 1,
      +          "type": "string"
      +        },
      +        "maxItems": 8,
      +        "type": "array"
      +      },
      +      "cost": {
      +        "additionalProperties": false,
      +        "description": "Coût de traitement par dossier pour cette étape.",
      +        "properties": {
      +          "note": {
      +            "description": "Précision libre sur le coût.",
      +            "maxLength": 120,
      +            "type": "string"
      +          },
      +          "perCaseUsd": {
      +            "description": "Coût de traitement par dossier/instance, en USD.",
      +            "maximum": 1000000,
      +            "minimum": 0,
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "perCaseUsd"
      +        ],
      +        "type": "object"
      +      },
      +      "duration": {
      +        "additionalProperties": false,
      +        "description": "Durée de traitement typique de cette étape.",
      +        "properties": {
      +          "unit": {
      +            "description": "Unité: minutes, heures ou jours.",
      +            "enum": [
      +              "min",
      +              "h",
      +              "d"
      +            ],
      +            "type": "string"
      +          },
      +          "value": {
      +            "description": "Valeur numérique de la durée.",
      +            "exclusiveMinimum": 0,
      +            "maximum": 100000,
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "value",
      +          "unit"
      +        ],
      +        "type": "object"
      +      },
      +      "executionPct": {
      +        "description": "% des instances du process qui passent réellement par cette étape (100 = chemin toujours emprunté).",
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "number"
      +      },
      +      "isBottleneck": {
      +        "description": "true pour marquer visuellement cette étape comme goulot d’étranglement identifié (durée/SLA problématique).",
      +        "type": "boolean"
      +      },
      +      "laneId": {
      +        "description": "ID de la lane parente (cellule processType='lane') à laquelle rattacher cette task/event — kebab-case, comme retourné par add_swimlane (ex: 'lane-sales').",
      +        "type": "string"
      +      },
      +      "processType": {
      +        "description": "Rôle BPMN-lite de la cellule — détermine sa forme sur le canvas : 'task' (rectangle), 'event-start'/'event-end' (cercle début/fin), 'event-intermediate-timer'/'event-intermediate-error' (cercle intermédiaire), 'gateway-xor'/'gateway-and'/'gateway-or' (losange de décision), 'subprocess' (rectangle double-bordure), 'lane' (couloir — normalement créé via add_swimlane, pas via add_kind_node directement).",
      +        "enum": [
      +          "task",
      +          "event-start",
      +          "event-end",
      +          "event-intermediate-timer",
      +          "event-intermediate-error",
      +          "gateway-xor",
      +          "gateway-and",
      +          "gateway-or",
      +          "subprocess",
      +          "lane"
      +        ],
      +        "type": "string"
      +      },
      +      "sla": {
      +        "additionalProperties": false,
      +        "description": "Délai maximum contractuel/cible pour cette étape (comparé à duration pour détecter les dépassements).",
      +        "properties": {
      +          "unit": {
      +            "description": "Unité: minutes, heures ou jours.",
      +            "enum": [
      +              "min",
      +              "h",
      +              "d"
      +            ],
      +            "type": "string"
      +          },
      +          "value": {
      +            "description": "Valeur numérique de la durée.",
      +            "exclusiveMinimum": 0,
      +            "maximum": 100000,
      +            "type": "number"
      +          }
      +        },
      +        "required": [
      +          "value",
      +          "unit"
      +        ],
      +        "type": "object"
      +      },
      +      "swimlaneOrder": {
      +        "description": "Ordre vertical au sein de la lane (rarement utilisé — à défaut, l’ordre des lanes suit `order`, puis l’id).",
      +        "maximum": 100,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "taskType": {
      +        "description": "Type d'exécutant pour une task : 'user' (humain via UI), 'service' (système/API), 'manual' (humain hors-système, ex: papier), 'script' (automatisation batch).",
      +        "enum": [
      +          "user",
      +          "service",
      +          "manual",
      +          "script"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "processType"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "additionalProperties": false,
      +    "properties": {
      +      "channel": {
      +        "description": "Canal principal via lequel cette interaction a lieu.",
      +        "enum": [
      +          "web",
      +          "email",
      +          "app",
      +          "phone",
      +          "in-person",
      +          "social",
      +          "sms",
      +          "chat",
      +          "push"
      +        ],
      +        "type": "string"
      +      },
      +      "channels": {
      +        "description": "Canaux multiples si le touchpoint est multi-canal (channel seul suffit pour un canal unique).",
      +        "items": {
      +          "enum": [
      +            "web",
      +            "email",
      +            "app",
      +            "phone",
      +            "in-person",
      +            "social",
      +            "sms",
      +            "chat",
      +            "push"
      +          ],
      +          "type": "string"
      +        },
      +        "maxItems": 8,
      +        "type": "array"
      +      },
      +      "emotion": {
      +        "anyOf": [
      +          {
      +            "const": -2,
      +            "type": "number"
      +          },
      +          {
      +            "const": -1,
      +            "type": "number"
      +          },
      +          {
      +            "const": 0,
      +            "type": "number"
      +          },
      +          {
      +            "const": 1,
      +            "type": "number"
      +          },
      +          {
      +            "const": 2,
      +            "type": "number"
      +          }
      +        ],
      +        "description": "Score émotionnel du client à cette étape, de -2 (très négatif/frustration) à +2 (très positif/enchantement), 0 = neutre. N'est PAS rendu comme courbe sur le canvas automatiquement (voir compute_emotion_curve pour l'agréger) — un score ≤ -1 signale typiquement un point de friction à documenter via une cellule 'pain' associée."
      +      },
      +      "isMomentOfTruth": {
      +        "description": "true pour marquer un instant décisif qui influence fortement la perception globale du client (mis en évidence visuellement).",
      +        "type": "boolean"
      +      },
      +      "journeyType": {
      +        "description": "Rôle de la cellule dans la carte de parcours : 'phase' (grande étape, colonne d'en-tête), 'step' (action concrète de l'utilisateur), 'touchpoint' (point de contact avec un canal/produit), 'pain' (point de friction/irritant), 'opportunity' (piste d'amélioration identifiée), 'headline' (bloc de titre/contexte libre).",
      +        "enum": [
      +          "phase",
      +          "step",
      +          "touchpoint",
      +          "pain",
      +          "opportunity",
      +          "headline"
      +        ],
      +        "type": "string"
      +      },
      +      "metrics": {
      +        "description": "Indicateurs chiffrés rattachés à cette étape (NPS, taux, durée...).",
      +        "items": {
      +          "additionalProperties": false,
      +          "properties": {
      +            "delta": {
      +              "description": "Variation affichée à côté de la valeur (ex: '+5 pts', '-2%').",
      +              "maxLength": 20,
      +              "type": "string"
      +            },
      +            "hint": {
      +              "description": "Info-bulle explicative (source de la donnée, période de mesure...).",
      +              "maxLength": 120,
      +              "type": "string"
      +            },
      +            "label": {
      +              "description": "Nom court de la métrique (ex: 'NPS', 'Taux de conversion').",
      +              "maxLength": 40,
      +              "minLength": 1,
      +              "type": "string"
      +            },
      +            "trend": {
      +              "description": "Sens de la flèche de tendance affichée avec delta.",
      +              "enum": [
      +                "up",
      +                "down",
      +                "flat"
      +              ],
      +              "type": "string"
      +            },
      +            "value": {
      +              "description": "Valeur affichée (ex: '42', '12.3%') — texte libre, pas forcément numérique.",
      +              "maxLength": 40,
      +              "minLength": 1,
      +              "type": "string"
      +            }
      +          },
      +          "required": [
      +            "label",
      +            "value"
      +          ],
      +          "type": "object"
      +        },
      +        "maxItems": 6,
      +        "type": "array"
      +      },
      +      "orderInPhase": {
      +        "description": "Ordre horizontal au sein de la phase (0 = en premier). Absent = append à droite.",
      +        "maximum": 1000,
      +        "minimum": 0,
      +        "type": "integer"
      +      },
      +      "phaseId": {
      +        "description": "ID de la phase parente (cellule journeyType='phase', créée via add_journey_phase) — positionne la cellule dans la bonne colonne.",
      +        "type": "string"
      +      },
      +      "quote": {
      +        "additionalProperties": false,
      +        "description": "Verbatim client illustrant ce point du parcours.",
      +        "properties": {
      +          "author": {
      +            "description": "Attribution (ex: 'Client B2B, 50 employés', prénom si connu).",
      +            "maxLength": 80,
      +            "type": "string"
      +          },
      +          "text": {
      +            "description": "Citation verbatim du client/utilisateur.",
      +            "maxLength": 280,
      +            "minLength": 1,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "text"
      +        ],
      +        "type": "object"
      +      },
      +      "severity": {
      +        "description": "Gravité d'un pain point ou priorité d'une opportunity.",
      +        "enum": [
      +          "low",
      +          "medium",
      +          "high"
      +        ],
      +        "type": "string"
      +      },
      +      "swimlane": {
      +        "description": "Couloir horizontal (modèle service blueprint) : 'customer' (actions visibles du client), 'frontstage' (interactions client-visibles côté entreprise), 'backstage' (opérations internes invisibles du client), 'support' (systèmes/process support).",
      +        "enum": [
      +          "customer",
      +          "frontstage",
      +          "backstage",
      +          "support"
      +        ],
      +        "type": "string"
      +      }
      +    },
      +    "required": [
      +      "journeyType"
      +    ],
      +    "type": "object"
      +  },
      +  {
      +    "oneOf": [
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "captableType": {
      +            "const": "holder",
      +            "description": "Discriminant fixe — identifie cette cellule comme un actionnaire/détenteur de titres (par opposition à un round).",
      +            "type": "string"
      +          },
      +          "holderType": {
      +            "description": "Catégorie de détenteur : 'founder' (co-fondateur), 'employee' (salarié avec BSPCE/options), 'investor' (VC/business angel), 'pool' (réserve ESOP non-allouée), 'entity' (personne morale, holding, SPV).",
      +            "enum": [
      +              "founder",
      +              "employee",
      +              "investor",
      +              "pool",
      +              "entity"
      +            ],
      +            "type": "string"
      +          },
      +          "isConcentrated": {
      +            "description": "true pour marquer ce holder comme signal de concentration (utilisé par validate_captable).",
      +            "type": "boolean"
      +          },
      +          "liquidationPreference": {
      +            "additionalProperties": false,
      +            "description": "Préférence de liquidation applicable (typique pour preferred).",
      +            "properties": {
      +              "dividendRatePct": {
      +                "description": "Taux de dividende cumulatif, en % annuel (ex: 8 pour 8%/an, défaut NVCA). Court en intérêt SIMPLE sur le montant investi entre la date du round et la date de sortie, ajouté par-dessus la préférence. Omettre pour aucun dividende.",
      +                "maximum": 100,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "multiplier": {
      +                "description": "Multiple de préférence de liquidation (ex: 1 = 1×, 2 = 2×) — montant récupéré en priorité = multiplier × montant investi.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 10,
      +                "type": "number"
      +              },
      +              "participating": {
      +                "description": "true = preferred \"participating\" (touche la préférence de liquidation PUIS participe aussi au pro-rata résiduel avec les common) ; false = \"non-participating\" (touche le max entre la préférence ET la conversion pro-rata en common, jamais les deux).",
      +                "type": "boolean"
      +              }
      +            },
      +            "required": [
      +              "multiplier",
      +              "participating"
      +            ],
      +            "type": "object"
      +          },
      +          "pricePerShare": {
      +            "description": "Prix payé par action lors de l'émission — absent pour un SAFE non converti.",
      +            "maximum": 1000000000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "safeTerms": {
      +            "additionalProperties": false,
      +            "description": "Termes du SAFE — requis si securityType='safe', ignoré sinon.",
      +            "properties": {
      +              "capBasis": {
      +                "description": "Base sur laquelle s'applique valuationCap. 'post-money' = convention YC SAFE v2 (la plus courante depuis 2018).",
      +                "enum": [
      +                  "post-money",
      +                  "pre-money"
      +                ],
      +                "type": "string"
      +              },
      +              "discountPct": {
      +                "description": "Remise en % sur le prix par action du prochain priced round (ex: 20 pour 20% de discount).",
      +                "maximum": 100,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "investmentUsd": {
      +                "description": "Montant investi via ce SAFE, en USD (ou monnaie du projet).",
      +                "maximum": 1000000000000,
      +                "minimum": 0,
      +                "type": "number"
      +              },
      +              "mfn": {
      +                "description": "Most Favored Nation — true si ce SAFE bénéficie automatiquement des termes plus favorables accordés à un SAFE ultérieur.",
      +                "type": "boolean"
      +              },
      +              "valuationCap": {
      +                "description": "Plafond de valorisation du SAFE — au-delà, le SAFE convertit comme si la valorisation était plafonnée à ce montant.",
      +                "exclusiveMinimum": 0,
      +                "maximum": 1000000000000,
      +                "type": "number"
      +              }
      +            },
      +            "type": "object"
      +          },
      +          "securityRound": {
      +            "description": "ID du round (cellule captableType='round') dans lequel ce titre a été émis — absent = émission fondatrice (t=0). UUID ou kebab-case, comme le reste des ids de cellule.",
      +            "type": "string"
      +          },
      +          "securityType": {
      +            "description": "Type de titre détenu : 'common' (actions ordinaires, typiquement fondateurs), 'preferred' (actions de préférence, typiquement investisseurs priced round), 'safe' (SAFE non converti — voir safeTerms), 'convertible' (obligation convertible), 'option' (stock-options/BSPCE non exercées).",
      +            "enum": [
      +              "common",
      +              "preferred",
      +              "safe",
      +              "convertible",
      +              "option"
      +            ],
      +            "type": "string"
      +          },
      +          "shares": {
      +            "description": "Nombre de parts/actions détenues (entier ou décimal selon la granularité du cap table).",
      +            "maximum": 1000000000000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "vestingSchedule": {
      +            "additionalProperties": false,
      +            "description": "Calendrier de vesting applicable à ces parts (typique pour founder/employee).",
      +            "properties": {
      +              "cliffMonths": {
      +                "description": "Durée du cliff en mois (période avant laquelle 0 part n'est acquise, ex: 12).",
      +                "maximum": 120,
      +                "minimum": 0,
      +                "type": "integer"
      +              },
      +              "startDate": {
      +                "description": "Date de début du vesting (YYYY-MM-DD).",
      +                "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +                "type": "string"
      +              },
      +              "totalMonths": {
      +                "description": "Durée totale du vesting en mois (ex: 48 pour un vesting standard 4 ans).",
      +                "maximum": 240,
      +                "minimum": 1,
      +                "type": "integer"
      +              }
      +            },
      +            "required": [
      +              "startDate",
      +              "cliffMonths",
      +              "totalMonths"
      +            ],
      +            "type": "object"
      +          }
      +        },
      +        "required": [
      +          "captableType",
      +          "holderType",
      +          "securityType",
      +          "shares"
      +        ],
      +        "type": "object"
      +      },
      +      {
      +        "additionalProperties": false,
      +        "properties": {
      +          "amountRaised": {
      +            "description": "Montant total levé lors de ce round.",
      +            "maximum": 1000000000000000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "captableType": {
      +            "const": "round",
      +            "description": "Discriminant fixe — identifie cette cellule comme un tour de financement (par opposition à un holder).",
      +            "type": "string"
      +          },
      +          "date": {
      +            "description": "Date de closing du round (YYYY-MM-DD).",
      +            "pattern": "^\\d{4}-\\d{2}-\\d{2}$",
      +            "type": "string"
      +          },
      +          "esopRefreshPct": {
      +            "description": "% de refresh du pool ESOP effectué à l'occasion de ce round.",
      +            "maximum": 100,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "name": {
      +            "description": "Nom du round (ex: 'Seed', 'Series A', 'Bridge').",
      +            "maxLength": 80,
      +            "minLength": 1,
      +            "type": "string"
      +          },
      +          "preMoneyValuation": {
      +            "description": "Valorisation pré-money du round, en monnaie du projet.",
      +            "maximum": 1000000000000000,
      +            "minimum": 0,
      +            "type": "number"
      +          },
      +          "riskTags": {
      +            "description": "Signaux de risque associés à ce round : 'down-round', 'concentration', 'underwater-options', 'anti-dilution'.",
      +            "items": {
      +              "enum": [
      +                "down-round",
      +                "concentration",
      +                "underwater-options",
      +                "anti-dilution"
      +              ],
      +              "type": "string"
      +            },
      +            "maxItems": 8,
      +            "type": "array"
      +          },
      +          "termSheetNote": {
      +            "description": "Note libre sur les conditions négociées (clauses particulières, board seat, pro-rata rights...).",
      +            "maxLength": 160,
      +            "type": "string"
      +          }
      +        },
      +        "required": [
      +          "captableType",
      +          "name",
      +          "date",
      +          "preMoneyValuation",
      +          "amountRaised"
      +        ],
      +        "type": "object"
      +      }
      +    ]
      +  }
      +]
    • changedInput schema / properties / x / description
      Previous value: -"Position X en pixels (React Flow). Omets ce champ (avec y/width/height) pour laisser resolveAutoPosition placer le nœud automatiquement selon son kind (ex: une task process atterrit dans sa lane, un step journey dans sa case (phase, swimlane))."New value: +"Position X en pixels (React Flow). Omis (avec y/width/height), le champ laisse resolveAutoPosition placer le nœud automatiquement selon son kind (ex: une task process atterrit dans sa lane, un step journey dans sa case (phase, swimlane))."
    • changedInput schema / properties / y / description
      Previous value: -"Position Y en pixels (React Flow). Voir x — laisser absent = auto-layout."New value: +"Position Y en pixels (React Flow). Voir x — absent = auto-layout."
  3. First observed

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare a non-destructive write (readOnlyHint=false, destructiveHint=false), so the safety profile is covered. The description adds real behavioral context: metadata is 'strictly validated per kind' (implying refusals on malformed input) and the kind must align with the project's primary_kind, both of which affect whether the call succeeds.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tightly packed sentences that are front-loaded with the core action and constraint. The 'ALL LIVE since May 2026' clause is a slightly noisy, low-value claim, keeping it from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 13-parameter, 4-required polymorphic creation tool with no output schema, the description covers the essential decisions (which kind, matching primary_kind, where to find metadata shape). Pointing to get_playbook closes the biggest gap, though it leaves return/ID behavior unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 13 parameters in depth. The description reinforces kind semantics and gives two metadata examples, but adds little that isn't already in the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Creates a node') and scopes it to the 4 polymorphic diagram kinds, naming them explicitly. It does not directly distinguish itself from siblings like add_cell/add_entity/add_swimlane in the description text (that differentiation lives only in the schema), so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a concrete usage rule ('kind must match the project's primary_kind unless the user explicitly asks to mix') and routes the agent to get_playbook for the per-kind metadata shape. It lacks explicit when-not/alternatives guidance against sibling creation tools, which the schema carries instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.