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"
+ }
+ ]
+ }
+]