Ontologies
Créer des packs d'ontologie — types d'objets, types de liens, types d'actions, règles d'identité et liaisons
Cet artefact est distribué dans un Pack. Pour le cycle de vie partagé — installation, pack build, upload — voir Packs & SDK d'authoring.
Une Ontologie est le système de types sur lequel votre tenant fonctionne : Customer, Asset, Risk, Incident, les relations entre eux (owns, affects, mitigates), et les actions typées que vous pouvez effectuer sur eux (AssignAsset, AssessRisk). Le SDK d'authoring vous permet de distribuer cela sous forme d'un pack d'ontologie versionné et validé.
Une ontologie est le système de types. Une base de connaissances est le contenu qui l'utilise. Ce sont des choses différentes — une ontologie, de nombreuses bases de connaissances. Plusieurs ontologies peuvent coexister dans un même tenant (par défaut + par domaine + importé via pack).
Installation
bun add -d @scrydon/sdk-authoring zodnpm install --save-dev @scrydon/sdk-authoring zodimport {
defineOntology,
defineObjectType,
defineLinkType,
defineActionType,
defineIdentityRule,
defineBinding,
defineProperty,
} from '@scrydon/sdk-authoring/ontologies'Ce que contient un pack
| Élément | Rôle |
|---|---|
| Object Type | Une entité typée — Customer, Asset, RiskFinding. A des properties, un kind (analytical / transactional / binding_only). |
| Link Type | Une relation typée — affects(RiskFinding → Customer). Cardinalité + nom de traversée inverse optionnel. |
| Action Type | Une mutation côté serveur contrôlée par OPA. Porte un schéma d'entrée Zod et un descripteur d'effet secondaire (object_edit / link_edit / outbox / webhook). |
| Identity Rule | Comment les instances sont dédupliquées. Clés de correspondance déterministes, ER probabiliste optionnel (signaux + seuils). |
| Binding | Relie une source en amont (silver_table, memex_page, process_flow_task, process_flow_action, extraction, stream, manual) à des instances d'objet ou de lien typées. |
Un exemple complet
import {
defineOntology,
defineObjectType,
defineLinkType,
defineActionType,
defineIdentityRule,
defineProperty,
} from '@scrydon/sdk-authoring/ontologies'
import { z } from 'zod'
export default defineOntology({
id: 'acme-crm',
version: '1.0.0',
displayName: 'ACME CRM',
description: 'Salesforce-style CRM ontology',
maturity: 'preview',
author: { name: 'Acme Inc.' },
objectTypes: [
defineObjectType({
slug: 'Account',
displayName: 'Account',
kind: 'transactional',
properties: [
defineProperty({
slug: 'name',
displayName: 'Legal name',
scalarType: 'string',
cardinality: 'required',
}),
defineProperty({
slug: 'jurisdiction',
displayName: 'Jurisdiction',
scalarType: 'string',
classification: 'internal',
}),
defineProperty({
slug: 'riskTier',
displayName: 'Risk tier',
scalarType: 'string',
piiFlags: ['regulatory'],
}),
],
}),
defineObjectType({
slug: 'Asset',
displayName: 'Asset',
kind: 'transactional',
properties: [
defineProperty({ slug: 'name', displayName: 'Name', scalarType: 'string' }),
defineProperty({ slug: 'value', displayName: 'Value', scalarType: 'float' }),
],
}),
],
linkTypes: [
defineLinkType({
slug: 'owns',
displayName: 'Owns',
sourceTypes: ['Account'],
targetTypes: ['Asset'],
cardinality: '1-N',
reverseName: 'ownedBy',
}),
],
actionTypes: [
defineActionType({
slug: 'AssignAsset',
displayName: 'Assign asset to account',
subjectTypeSlug: 'Asset',
inputZod: z.object({ accountId: z.string().uuid() }),
sideEffectDescriptor: { kind: 'link_edit' },
}),
],
identityRules: [
defineIdentityRule({
objectTypeSlug: 'Account',
deterministicKeys: ['name', 'jurisdiction'],
}),
],
bindings: [],
})Modèle de propriété
| Champ | Notes |
|---|---|
scalarType | L'un de string, int, float, bool, uuid, timestamp, date, json, bytes |
cardinality | required, optional ou many |
classification | public, internal, confidential, restricted — alimente le DLP et le RBAC |
piiFlags | Tags libres exposés à la rédaction DLP au moment de la récupération |
Types de kinds d'Object Type
analytical— faits en masse, lecture intensive. Supporté par une liaisonsilver_table.transactional— entités modifiables (saisie manuelle, sortie de process-flow). Natif Postgres.binding_only— projection en lecture seule uniquement (ex.memex_page,extraction). Jamais directement modifié.
Liaisons — les sept kinds
| Kind | Relie |
|---|---|
silver_table | Une table analytique bronze/silver → un type d'objet |
memex_page | Un nœud de contenu KB Memex (correspondance slug/alias) → une instance d'objet |
process_flow_task | Une ligne process_instance_task → une instance d'objet typée |
process_flow_action | Un process_instance_task_action de actionType=entity_link → une instance de lien typée |
extraction | Le pipeline d'extraction analytics 5-WF → une instance d'objet |
stream | Une source de streaming (Kafka, webhook fanout) → une instance d'objet |
manual | Saisie directe dans le workbench → une instance d'objet |
defineBinding({
objectTypeSlug: 'Account',
kind: 'silver_table',
source: { table: 'silver_account' },
identitySpec: { keys: ['external_id'] },
columnMap: { name: 'legal_name', jurisdiction: 'country_code' },
})Visualisation du graphe
Les packs denses peuvent inclure des indications optionnelles de visualisation de graphe. Ces indications ne modifient pas le schéma d'ontologie ; elles indiquent aux surfaces de graphe comment restituer efficacement une vue d'instance.
Utilisez mode: 'compact' quand un pack a un type d'objet racine de haute valeur et de nombreuses liaisons enfant de haute cardinalité. Le point de terminaison du graphe ne projette que la liaison racine, affiche des nœuds agrégés par instance racine, et ignore la projection de lignes pour les liaisons d'objet et de lien réduites.
defineOntology({
id: 'acme-docs',
version: '1.0.0',
displayName: 'ACME Documents',
description: 'Document intelligence ontology',
maturity: 'preview',
author: { name: 'Acme Inc.' },
visualization: {
graph: {
mode: 'compact',
rootObjectType: 'DocumentCorpus',
rootLimit: 100,
rootGroup: {
slug: 'DocumentCorpusIndex',
label: 'All document corpora',
edgeLabel: 'contains corpus',
},
collapsedObjectTypes: ['Document', 'DocumentSection', 'ExtractedEntity'],
collapsedLinkTypes: ['ContainsDocument', 'MentionsEntity'],
aggregates: [
{
slug: 'Document',
label: 'Documents',
linkSlug: 'ContainsDocument',
edgeLabel: 'contains documents',
countObjectTypes: ['Document'],
},
{
slug: 'ExtractedEntity',
label: 'Extracted entities',
linkSlug: 'MentionsEntity',
edgeLabel: 'mentions entities',
countObjectTypes: ['ExtractedEntity'],
countLinkTypes: ['MentionsEntity'],
},
],
},
},
objectTypes: [],
linkTypes: [],
actionTypes: [],
identityRules: [],
bindings: [],
})Règles d'identité — déterministes + probabilistes
Les règles d'identité indiquent à la plateforme comment fusionner les instances. Le chemin déterministe est obligatoire ; le chemin probabiliste est optionnel pour les sources plus floues.
defineIdentityRule({
objectTypeSlug: 'Account',
deterministicKeys: ['external_id', 'name + jurisdiction'],
probabilistic: {
blockingKeys: ['name'],
signals: [
{ name: 'name_levenshtein', weight: 0.6, on: 'name' },
{ name: 'jurisdiction_match', weight: 0.4, on: 'jurisdiction' },
],
thresholds: { auto: 0.85, review: 0.70 },
},
})Types d'actions — mutations côté serveur contrôlées par OPA
Les types d'actions sont le seul chemin d'écriture typé. Chaque action s'exécute de la même façon :
- Validation Zod de l'entrée contre
inputZod. - OPA évalue
policyRegistry.evaluate({ resource_type: 'action', action: <slug>, ... }). - Le descripteur d'effet secondaire décide de ce qui s'exécute — édition directe d'objet/lien, dispatch d'outbox, ou webhook.
- La ligne d'audit est écrite avec
bundleHash+policy_execution_grant.grantId.
sideEffectDescriptor.kind | Ce qui se passe |
|---|---|
object_edit | Upsert dans le store transactionnel du type d'objet |
link_edit | Upsert dans le store d'arêtes du type de lien |
outbox | Mise en file d'attente d'un événement d'outbox transactionnel |
webhook | Déclenchement d'un webhook configuré (URL dans config) |
Maturité
Choisissez-en une — affichée comme un badge dans le workbench :
verified— prêt pour la production, possédé et maintenupreview— fonctionnellement complet, peut évoluerexperimental— accès anticipé, s'attendre à des changements cassants
Validation
Le pack est validé contre OntologyManifestSchema (Zod) au moment du build et à nouveau côté serveur au moment du téléversement. Échecs courants :
| Erreur | Cause |
|---|---|
id must be lowercase kebab-case | L'id du Pack doit correspondre à /^[a-z][a-z0-9-]*$/ |
Slug must start with a letter, alnum + _ - | Le slug d'objet/lien/action/propriété a échoué le regex |
Must be a valid semver string | version n'est pas semver |
linkType source/target slug not found | sourceTypes / targetTypes référencent un slug de type d'objet inconnu |
Pack comme bundle d'intégration (aujourd'hui)
Les packs d'ontologie sont distribués dans un bundle d'intégration via definePackOntology — la couche de registre dispatche les packs de la même façon qu'elle dispatche les vendeurs. Un CLI autonome scrydon-ontologies est prévu ; en attendant, suivez le flux de build Intégrations avec un export definePackOntology(...) de niveau supérieur.
import { definePackOntology } from '@scrydon/sdk-authoring/integrations/define'
import myCrmOntology from './crm.ontology'
export default definePackOntology({
id: 'acme-crm',
version: '1.0.0',
displayName: 'ACME CRM',
description: 'Salesforce-style CRM ontology',
maturity: 'preview',
author: { name: 'Acme Inc.' },
objectTypes: myCrmOntology.objectTypes,
linkTypes: myCrmOntology.linkTypes,
actionTypes: myCrmOntology.actionTypes,
bindings: myCrmOntology.bindings,
identityRules: myCrmOntology.identityRules,
})