@elevasis/sdk 1.22.0 → 1.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -895,7 +895,6 @@ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
895
895
  table: entity.table
896
896
  }
897
897
  } : {},
898
- legacyEntityId: entity.id,
899
898
  ...entity.rowSchema !== void 0 ? { rowSchema: entity.rowSchema } : {},
900
899
  ...entity.stateCatalogId !== void 0 ? { stateCatalogId: entity.stateCatalogId } : {}
901
900
  };
@@ -920,8 +919,7 @@ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
920
919
  from: legacyObjectId(entity),
921
920
  to: legacyObjectId(targetEntity),
922
921
  cardinality: link.kind,
923
- ...link.via !== void 0 ? { via: link.via } : {},
924
- legacyEntityId: entity.id
922
+ ...link.via !== void 0 ? { via: link.via } : {}
925
923
  };
926
924
  addRecord(index, diagnostics, sourcesById, "linkTypes", linkType, {
927
925
  source: "legacy.entities.links",
@@ -979,8 +977,7 @@ function addSystemContentProjections(index, diagnostics, sourcesById, systemPath
979
977
  kind: node.type,
980
978
  ...typeof node.data?.["entityId"] === "string" ? { appliesTo: formatOntologyId({ scope: systemPath, kind: "object", localId: node.data["entityId"] }) } : {},
981
979
  ...Object.keys(entries).length > 0 ? { entries } : {},
982
- ...node.data !== void 0 ? { data: node.data } : {},
983
- legacyContentId: `${systemPath}:${localId}`
980
+ ...node.data !== void 0 ? { data: node.data } : {}
984
981
  };
985
982
  addRecord(index, diagnostics, sourcesById, "catalogTypes", catalogType, {
986
983
  source: "legacy.system.content",
@@ -1535,11 +1532,20 @@ EventEmissionDescriptorSchema.extend({
1535
1532
  ownerKind: z.enum(["resource", "entity"]).meta({ label: "Owner kind" })
1536
1533
  });
1537
1534
  var ResourceOntologyBindingSchema = z.object({
1538
- implements: z.array(OntologyIdSchema).optional(),
1535
+ actions: z.array(OntologyIdSchema).optional(),
1536
+ primaryAction: OntologyIdSchema.optional(),
1539
1537
  reads: z.array(OntologyIdSchema).optional(),
1540
1538
  writes: z.array(OntologyIdSchema).optional(),
1541
1539
  usesCatalogs: z.array(OntologyIdSchema).optional(),
1542
1540
  emits: z.array(OntologyIdSchema).optional()
1541
+ }).superRefine((binding, ctx) => {
1542
+ if (binding.primaryAction === void 0) return;
1543
+ if (binding.actions?.includes(binding.primaryAction)) return;
1544
+ ctx.addIssue({
1545
+ code: z.ZodIssueCode.custom,
1546
+ path: ["primaryAction"],
1547
+ message: "Resource ontology primaryAction must be included in actions"
1548
+ });
1543
1549
  });
1544
1550
  var CodeReferenceSchema = z.object({
1545
1551
  path: z.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
@@ -1554,6 +1560,10 @@ var ResourceEntryBaseSchema = z.object({
1554
1560
  order: z.number().default(0),
1555
1561
  /** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
1556
1562
  systemPath: SystemPathSchema.meta({ ref: "system" }),
1563
+ /** Executable display title owned by the OM Resource descriptor. */
1564
+ title: LabelSchema.optional(),
1565
+ /** Executable display description owned by the OM Resource descriptor. */
1566
+ description: DescriptionSchema.optional(),
1557
1567
  /** Optional role responsible for maintaining this resource. */
1558
1568
  ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
1559
1569
  status: ResourceGovernanceStatusSchema,
@@ -1568,8 +1578,6 @@ var ResourceEntryBaseSchema = z.object({
1568
1578
  });
1569
1579
  var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
1570
1580
  kind: z.literal("workflow"),
1571
- /** Mirrors WorkflowConfig.actionKey when the runtime workflow has one. */
1572
- actionKey: z.string().trim().min(1).max(255).optional(),
1573
1581
  emits: z.array(EventEmissionDescriptorSchema).optional()
1574
1582
  });
1575
1583
  var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
@@ -1609,6 +1617,30 @@ var ResourcesDomainSchema = z.record(z.string(), ResourceEntrySchema).refine((re
1609
1617
  message: "Each resource entry id must match its map key"
1610
1618
  }).default({});
1611
1619
  var DEFAULT_ORGANIZATION_MODEL_RESOURCES = {};
1620
+ function defineResource(resource) {
1621
+ return ResourceEntrySchema.parse(resource);
1622
+ }
1623
+ function defineResources(resources) {
1624
+ return Object.fromEntries(
1625
+ Object.entries(resources).map(([key, resource]) => [key, ResourceEntrySchema.parse(resource)])
1626
+ );
1627
+ }
1628
+ function ontologyIdFrom(input) {
1629
+ return typeof input === "string" ? input : input.id;
1630
+ }
1631
+ function ontologyIdArrayFrom(input) {
1632
+ return input?.map(ontologyIdFrom);
1633
+ }
1634
+ function defineResourceOntology(input) {
1635
+ return ResourceOntologyBindingSchema.parse({
1636
+ actions: ontologyIdArrayFrom(input.actions),
1637
+ primaryAction: input.primaryAction === void 0 ? void 0 : ontologyIdFrom(input.primaryAction),
1638
+ reads: ontologyIdArrayFrom(input.reads),
1639
+ writes: ontologyIdArrayFrom(input.writes),
1640
+ usesCatalogs: ontologyIdArrayFrom(input.usesCatalogs),
1641
+ emits: ontologyIdArrayFrom(input.emits)
1642
+ });
1643
+ }
1612
1644
 
1613
1645
  // ../core/src/organization-model/domains/roles.ts
1614
1646
  var RoleIdSchema = ModelIdSchema;
@@ -1789,6 +1821,170 @@ var OrgKnowledgeNodeSchema = z.object({
1789
1821
  updatedAt: z.string().trim().min(1).max(50)
1790
1822
  });
1791
1823
  var KnowledgeDomainSchema = z.record(ModelIdSchema, OrgKnowledgeNodeSchema).default({});
1824
+ var SecretLikeMetadataKeySchema = /(?:secret|password|passwd|token|api[-_]?key|credential|private[-_]?key)/i;
1825
+ var SecretLikeMetadataValueSchema = /(?:sk-[A-Za-z0-9_-]{12,}|pk_live_[A-Za-z0-9_-]{12,}|eyJ[A-Za-z0-9_-]{20,}|-----BEGIN (?:RSA |OPENSSH |EC )?PRIVATE KEY-----)/;
1826
+ var OmTopologyNodeKindSchema = z.enum([
1827
+ "system",
1828
+ "resource",
1829
+ "ontology",
1830
+ "policy",
1831
+ "role",
1832
+ "trigger",
1833
+ "humanCheckpoint",
1834
+ "externalResource"
1835
+ ]);
1836
+ var OmTopologyRelationshipKindSchema = z.enum(["triggers", "uses", "approval"]);
1837
+ var OmTopologyNodeRefSchema = z.discriminatedUnion("kind", [
1838
+ z.object({ kind: z.literal("system"), id: ModelIdSchema }),
1839
+ z.object({ kind: z.literal("resource"), id: ResourceIdSchema }),
1840
+ z.object({ kind: z.literal("ontology"), id: OntologyIdSchema }),
1841
+ z.object({ kind: z.literal("policy"), id: ModelIdSchema }),
1842
+ z.object({ kind: z.literal("role"), id: ModelIdSchema }),
1843
+ z.object({ kind: z.literal("trigger"), id: ResourceIdSchema }),
1844
+ z.object({ kind: z.literal("humanCheckpoint"), id: ResourceIdSchema }),
1845
+ z.object({ kind: z.literal("externalResource"), id: ResourceIdSchema })
1846
+ ]);
1847
+ var OmTopologyMetadataSchema = z.record(z.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
1848
+ function visit(value, path) {
1849
+ if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
1850
+ ctx.addIssue({
1851
+ code: z.ZodIssueCode.custom,
1852
+ path,
1853
+ message: "Topology metadata must not contain secret-like values"
1854
+ });
1855
+ return;
1856
+ }
1857
+ if (Array.isArray(value)) {
1858
+ value.forEach((entry, index) => visit(entry, [...path, index]));
1859
+ return;
1860
+ }
1861
+ if (typeof value !== "object" || value === null) return;
1862
+ Object.entries(value).forEach(([key, entry]) => {
1863
+ if (SecretLikeMetadataKeySchema.test(key)) {
1864
+ ctx.addIssue({
1865
+ code: z.ZodIssueCode.custom,
1866
+ path: [...path, key],
1867
+ message: `Topology metadata key "${key}" looks secret-like`
1868
+ });
1869
+ }
1870
+ visit(entry, [...path, key]);
1871
+ });
1872
+ }
1873
+ visit(metadata, []);
1874
+ });
1875
+ var OmTopologyRelationshipSchema = z.object({
1876
+ from: OmTopologyNodeRefSchema,
1877
+ kind: OmTopologyRelationshipKindSchema,
1878
+ to: OmTopologyNodeRefSchema,
1879
+ systemPath: SystemPathSchema.optional(),
1880
+ required: z.boolean().optional(),
1881
+ metadata: OmTopologyMetadataSchema.optional()
1882
+ });
1883
+ var OmTopologyDomainSchema = z.object({
1884
+ version: z.literal(1).default(1),
1885
+ relationships: z.record(z.string().trim().min(1).max(255), OmTopologyRelationshipSchema).default({})
1886
+ }).default({ version: 1, relationships: {} });
1887
+ var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
1888
+ version: 1,
1889
+ relationships: {}
1890
+ };
1891
+ function idFrom(input) {
1892
+ return typeof input === "string" ? input : input.id;
1893
+ }
1894
+ function parseRef(kind, id) {
1895
+ return OmTopologyNodeRefSchema.parse({ kind, id });
1896
+ }
1897
+ function isNodeRef(input) {
1898
+ return OmTopologyNodeRefSchema.safeParse(input).success;
1899
+ }
1900
+ function isResourceEntry(input) {
1901
+ if (typeof input !== "object" || input === null) return false;
1902
+ const candidate = input;
1903
+ return typeof candidate.id === "string" && typeof candidate.systemPath === "string" && typeof candidate.status === "string" && ["workflow", "agent", "integration", "script"].includes(String(candidate.kind));
1904
+ }
1905
+ var topologyRef = {
1906
+ system: (system) => parseRef("system", idFrom(system)),
1907
+ resource: (resource) => parseRef("resource", idFrom(resource)),
1908
+ ontology: (record) => parseRef("ontology", idFrom(record)),
1909
+ policy: (policy) => parseRef("policy", idFrom(policy)),
1910
+ role: (role) => parseRef("role", idFrom(role)),
1911
+ trigger: (trigger) => parseRef("trigger", idFrom(trigger)),
1912
+ humanCheckpoint: (checkpoint) => parseRef("humanCheckpoint", idFrom(checkpoint)),
1913
+ externalResource: (externalResource) => parseRef("externalResource", idFrom(externalResource))
1914
+ };
1915
+ var topologyRelationship = {
1916
+ triggers: (from, to, options = {}) => defineTopologyRelationship({
1917
+ ...options,
1918
+ from,
1919
+ kind: "triggers",
1920
+ to
1921
+ }),
1922
+ uses: (from, to, options = {}) => defineTopologyRelationship({
1923
+ ...options,
1924
+ from,
1925
+ kind: "uses",
1926
+ to
1927
+ }),
1928
+ approval: (from, to, options = {}) => defineTopologyRelationship({
1929
+ ...options,
1930
+ from,
1931
+ kind: "approval",
1932
+ to
1933
+ }),
1934
+ usesIntegration: (from, integration, options = {}) => defineTopologyRelationship({
1935
+ required: true,
1936
+ ...options,
1937
+ from,
1938
+ kind: "uses",
1939
+ to: integration
1940
+ }),
1941
+ requestsApproval: (from, checkpoint, options = {}) => defineTopologyRelationship({
1942
+ required: true,
1943
+ ...options,
1944
+ from,
1945
+ kind: "approval",
1946
+ to: topologyRef.humanCheckpoint(checkpoint)
1947
+ }),
1948
+ checkpointRoutesTo: (checkpoint, to, options = {}) => defineTopologyRelationship({
1949
+ required: true,
1950
+ ...options,
1951
+ from: topologyRef.humanCheckpoint(checkpoint),
1952
+ kind: "triggers",
1953
+ to
1954
+ })
1955
+ };
1956
+ function compileTopologyNodeRef(input) {
1957
+ if (isNodeRef(input)) return input;
1958
+ if (isResourceEntry(input)) return topologyRef.resource(input);
1959
+ throw new Error("Topology node refs must be typed node objects or serializable { kind, id } refs");
1960
+ }
1961
+ function parseTopologyNodeRef(input) {
1962
+ if (typeof input !== "string") return OmTopologyNodeRefSchema.parse(input);
1963
+ const separatorIndex = input.indexOf(":");
1964
+ if (separatorIndex === -1) {
1965
+ throw new Error(`Topology node ref "${input}" must use <kind>:<id>`);
1966
+ }
1967
+ const kind = input.slice(0, separatorIndex);
1968
+ const id = input.slice(separatorIndex + 1);
1969
+ if (!OmTopologyNodeKindSchema.safeParse(kind).success) {
1970
+ throw new Error(`Topology node ref "${input}" has unsupported kind "${kind}"`);
1971
+ }
1972
+ return OmTopologyNodeRefSchema.parse({ kind, id });
1973
+ }
1974
+ function defineTopologyRelationship(input) {
1975
+ return OmTopologyRelationshipSchema.parse({
1976
+ ...input,
1977
+ from: compileTopologyNodeRef(input.from),
1978
+ to: compileTopologyNodeRef(input.to)
1979
+ });
1980
+ }
1981
+ function defineTopology(relationships) {
1982
+ const entries = Array.isArray(relationships) ? relationships.map((relationship, index) => [`relationship-${index + 1}`, relationship]) : Object.entries(relationships);
1983
+ return OmTopologyDomainSchema.parse({
1984
+ version: 1,
1985
+ relationships: Object.fromEntries(entries.map(([key, relationship]) => [key, defineTopologyRelationship(relationship)]))
1986
+ });
1987
+ }
1792
1988
  var PolicyIdSchema = ModelIdSchema;
1793
1989
  var PolicyApplicabilitySchema = z.object({
1794
1990
  systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
@@ -1878,6 +2074,7 @@ z.enum([
1878
2074
  "systems",
1879
2075
  "ontology",
1880
2076
  "resources",
2077
+ "topology",
1881
2078
  "actions",
1882
2079
  "entities",
1883
2080
  "policies",
@@ -1897,6 +2094,7 @@ var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
1897
2094
  systems: { version: 1, lastModified: "2026-05-10" },
1898
2095
  ontology: { version: 1, lastModified: "2026-05-14" },
1899
2096
  resources: { version: 1, lastModified: "2026-05-10" },
2097
+ topology: { version: 1, lastModified: "2026-05-14" },
1900
2098
  actions: { version: 1, lastModified: "2026-05-10" },
1901
2099
  entities: { version: 1, lastModified: "2026-05-10" },
1902
2100
  policies: { version: 1, lastModified: "2026-05-10" },
@@ -1912,6 +2110,7 @@ var OrganizationModelDomainMetadataByDomainSchema = z.object({
1912
2110
  systems: OrganizationModelDomainMetadataSchema,
1913
2111
  ontology: OrganizationModelDomainMetadataSchema,
1914
2112
  resources: OrganizationModelDomainMetadataSchema,
2113
+ topology: OrganizationModelDomainMetadataSchema,
1915
2114
  actions: OrganizationModelDomainMetadataSchema,
1916
2115
  entities: OrganizationModelDomainMetadataSchema,
1917
2116
  policies: OrganizationModelDomainMetadataSchema,
@@ -1930,6 +2129,7 @@ var OrganizationModelSchemaBase = z.object({
1930
2129
  systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
1931
2130
  ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
1932
2131
  resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
2132
+ topology: OmTopologyDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_TOPOLOGY),
1933
2133
  actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
1934
2134
  entities: EntitiesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ENTITIES),
1935
2135
  policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
@@ -2272,6 +2472,25 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
2272
2472
  surface: ontologyCompilation.ontology.surfaces
2273
2473
  };
2274
2474
  const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index) => Object.keys(index)));
2475
+ function topologyTargetExists(ref) {
2476
+ if (ref.kind === "system") return systemsById.has(ref.id);
2477
+ if (ref.kind === "resource") return resourcesById.has(ref.id);
2478
+ if (ref.kind === "ontology") return ontologyIds.has(ref.id);
2479
+ if (ref.kind === "policy") return policiesById.has(ref.id);
2480
+ if (ref.kind === "role") return rolesById.has(ref.id);
2481
+ return true;
2482
+ }
2483
+ Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
2484
+ ["from", "to"].forEach((side) => {
2485
+ const ref = relationship[side];
2486
+ if (topologyTargetExists(ref)) return;
2487
+ addIssue(
2488
+ ctx,
2489
+ ["topology", "relationships", relationshipId, side],
2490
+ `Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
2491
+ );
2492
+ });
2493
+ });
2275
2494
  const ontologyReferenceKeyKinds = {
2276
2495
  valueType: "value-type",
2277
2496
  catalogType: "catalog",
@@ -2410,11 +2629,18 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
2410
2629
  }
2411
2630
  });
2412
2631
  function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
2413
- ids?.forEach((ontologyId, ontologyIndex) => {
2632
+ const ontologyIds2 = ids === void 0 ? [] : Array.isArray(ids) ? ids : [ids];
2633
+ ontologyIds2.forEach((ontologyId, ontologyIndex) => {
2414
2634
  if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
2415
2635
  addIssue(
2416
2636
  ctx,
2417
- ["resources", resourceId, "ontology", bindingKey, ontologyIndex],
2637
+ [
2638
+ "resources",
2639
+ resourceId,
2640
+ "ontology",
2641
+ bindingKey,
2642
+ ...Array.isArray(ids) ? [ontologyIndex] : []
2643
+ ],
2418
2644
  `Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
2419
2645
  );
2420
2646
  }
@@ -2423,7 +2649,8 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
2423
2649
  Object.values(model.resources).forEach((resource) => {
2424
2650
  const binding = resource.ontology;
2425
2651
  if (binding === void 0) return;
2426
- validateResourceOntologyBinding(resource.id, "implements", "action", binding.implements);
2652
+ validateResourceOntologyBinding(resource.id, "actions", "action", binding.actions);
2653
+ validateResourceOntologyBinding(resource.id, "primaryAction", "action", binding.primaryAction);
2427
2654
  validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
2428
2655
  validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
2429
2656
  validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
@@ -2870,6 +3097,119 @@ function getRuntimeResources(resources) {
2870
3097
  }))
2871
3098
  ];
2872
3099
  }
3100
+ function hasOntologySources(organizationModel) {
3101
+ return organizationModel.ontology !== void 0 || organizationModel.entities !== void 0 || organizationModel.actions !== void 0 || Object.values(organizationModel.systems ?? {}).some(systemHasOntologySource);
3102
+ }
3103
+ function systemHasOntologySource(system) {
3104
+ if (system.ontology !== void 0 || system.content !== void 0 && Object.keys(system.content).length > 0) return true;
3105
+ return Object.values(system.systems ?? system.subsystems ?? {}).some(systemHasOntologySource);
3106
+ }
3107
+ function ontologyIndexForKind(index, kind) {
3108
+ switch (kind) {
3109
+ case "object":
3110
+ return index.objectTypes;
3111
+ case "link":
3112
+ return index.linkTypes;
3113
+ case "action":
3114
+ return index.actionTypes;
3115
+ case "catalog":
3116
+ return index.catalogTypes;
3117
+ case "event":
3118
+ return index.eventTypes;
3119
+ case "interface":
3120
+ return index.interfaceTypes;
3121
+ case "value-type":
3122
+ return index.valueTypes;
3123
+ case "property":
3124
+ return index.sharedProperties;
3125
+ case "group":
3126
+ return index.groups;
3127
+ case "surface":
3128
+ return index.surfaces;
3129
+ }
3130
+ }
3131
+ function sameJson(left, right) {
3132
+ return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
3133
+ }
3134
+ function addOntologyBindingIssues(issues, orgName, resource, ontologyIndex) {
3135
+ const binding = resource.ontology;
3136
+ if (binding === void 0) return;
3137
+ if ((resource.kind === "workflow" || resource.kind === "agent") && (binding.actions?.length ?? 0) === 0) {
3138
+ addGovernanceIssue(
3139
+ issues,
3140
+ "missing-ontology-actions",
3141
+ orgName,
3142
+ resource.id,
3143
+ `[${orgName}] Resource '${resource.id}' declares ontology bindings but no ontology actions.`
3144
+ );
3145
+ }
3146
+ if (binding.primaryAction !== void 0 && !binding.actions?.includes(binding.primaryAction)) {
3147
+ addGovernanceIssue(
3148
+ issues,
3149
+ "primary-action-mismatch",
3150
+ orgName,
3151
+ resource.id,
3152
+ `[${orgName}] Resource '${resource.id}' primaryAction '${binding.primaryAction}' must be included in ontology.actions.`
3153
+ );
3154
+ }
3155
+ if (ontologyIndex === void 0) return;
3156
+ const validateRefs = (bindingKey, expectedKind, refs) => {
3157
+ const values = refs === void 0 ? [] : Array.isArray(refs) ? refs : [refs];
3158
+ const index = ontologyIndexForKind(ontologyIndex, expectedKind);
3159
+ for (const ref of values) {
3160
+ if (index[ref] !== void 0) continue;
3161
+ addGovernanceIssue(
3162
+ issues,
3163
+ "ontology-reference-missing",
3164
+ orgName,
3165
+ resource.id,
3166
+ `[${orgName}] Resource '${resource.id}' ontology.${bindingKey} references missing ${expectedKind} ontology record '${ref}'.`
3167
+ );
3168
+ }
3169
+ };
3170
+ validateRefs("actions", "action", binding.actions);
3171
+ validateRefs("primaryAction", "action", binding.primaryAction);
3172
+ validateRefs("reads", "object", binding.reads);
3173
+ validateRefs("writes", "object", binding.writes);
3174
+ validateRefs("usesCatalogs", "catalog", binding.usesCatalogs);
3175
+ validateRefs("emits", "event", binding.emits);
3176
+ }
3177
+ function addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex) {
3178
+ const relationships = organizationModel.topology?.relationships;
3179
+ if (relationships === void 0) return;
3180
+ const rolesById = new Set(Object.keys(organizationModel.roles ?? {}));
3181
+ const policiesById = new Set(Object.keys(organizationModel.policies ?? {}));
3182
+ const triggerIds = new Set(deployment.triggers?.map((trigger) => trigger.resourceId) ?? []);
3183
+ const humanCheckpointIds = new Set(deployment.humanCheckpoints?.map((checkpoint) => checkpoint.resourceId) ?? []);
3184
+ const externalResourceIds = new Set(deployment.externalResources?.map((external) => external.resourceId) ?? []);
3185
+ const topologyRefExists = (ref) => {
3186
+ if (ref.kind === "system") return systemsById.has(ref.id);
3187
+ if (ref.kind === "resource") return omResourcesById.has(ref.id);
3188
+ if (ref.kind === "policy") return policiesById.has(ref.id);
3189
+ if (ref.kind === "role") return rolesById.has(ref.id);
3190
+ if (ref.kind === "trigger") return triggerIds.has(ref.id);
3191
+ if (ref.kind === "humanCheckpoint") return humanCheckpointIds.has(ref.id);
3192
+ if (ref.kind === "externalResource") return externalResourceIds.has(ref.id);
3193
+ if (ref.kind === "ontology") {
3194
+ if (ontologyIndex === void 0) return true;
3195
+ return Object.values(ontologyIndex).some((records) => records[ref.id] !== void 0);
3196
+ }
3197
+ return false;
3198
+ };
3199
+ for (const [relationshipId, relationship] of Object.entries(relationships)) {
3200
+ ["from", "to"].forEach((side) => {
3201
+ const ref = relationship[side];
3202
+ if (topologyRefExists(ref)) return;
3203
+ addGovernanceIssue(
3204
+ issues,
3205
+ "topology-reference-missing",
3206
+ orgName,
3207
+ ref.id,
3208
+ `[${orgName}] Topology relationship '${relationshipId}' ${side} references missing ${ref.kind} '${ref.id}'.`
3209
+ );
3210
+ });
3211
+ }
3212
+ }
2873
3213
  function validateResourceGovernance(orgName, deployment, organizationModel = deployment.organizationModel, options = {}) {
2874
3214
  const mode = getResourceValidatorMode(options.mode);
2875
3215
  const omResourcesMap = organizationModel?.resources;
@@ -2885,6 +3225,17 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
2885
3225
  const omResourcesById = new Map(activeOmResources.map((resource) => [resource.id, resource]));
2886
3226
  const runtimeResources = getRuntimeResources(deployment);
2887
3227
  const runtimeResourcesById = new Map(runtimeResources.map((resource) => [resource.resourceId, resource]));
3228
+ const ontologyCompilation = hasOntologySources(organizationModel) ? compileOrganizationOntology(organizationModel) : void 0;
3229
+ const ontologyIndex = ontologyCompilation?.ontology;
3230
+ for (const diagnostic of ontologyCompilation?.diagnostics ?? []) {
3231
+ addGovernanceIssue(
3232
+ issues,
3233
+ "ontology-reference-missing",
3234
+ orgName,
3235
+ diagnostic.id,
3236
+ `[${orgName}] ${diagnostic.message}`
3237
+ );
3238
+ }
2888
3239
  for (const resource of activeOmResources) {
2889
3240
  if (!systemsById.has(resource.systemPath)) {
2890
3241
  addGovernanceIssue(
@@ -2924,6 +3275,16 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
2924
3275
  `[${orgName}] Resource '${resource.id}' system mismatch: code descriptor has '${runtimeResource.descriptor.systemPath}', OM has '${resource.systemPath}'.`
2925
3276
  );
2926
3277
  }
3278
+ if (runtimeResource.descriptor && !sameJson(runtimeResource.descriptor.ontology, resource.ontology)) {
3279
+ addGovernanceIssue(
3280
+ issues,
3281
+ "descriptor-mismatch",
3282
+ orgName,
3283
+ resource.id,
3284
+ `[${orgName}] Resource '${resource.id}' ontology descriptor mismatch between code and OM.`
3285
+ );
3286
+ }
3287
+ addOntologyBindingIssues(issues, orgName, resource, ontologyIndex);
2927
3288
  }
2928
3289
  for (const runtimeResource of runtimeResources) {
2929
3290
  const omResource = omResourcesById.get(runtimeResource.resourceId);
@@ -2965,6 +3326,7 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
2965
3326
  );
2966
3327
  }
2967
3328
  }
3329
+ addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex);
2968
3330
  emitGovernanceIssues(issues, mode, options.onWarning);
2969
3331
  return {
2970
3332
  valid: issues.length === 0,
@@ -6345,6 +6707,17 @@ var ResourceRegistry = class {
6345
6707
  return cache.commandView;
6346
6708
  }
6347
6709
  };
6710
+
6711
+ // ../core/src/platform/registry/types.ts
6712
+ function bindResourceDescriptor(definition) {
6713
+ const { resource, ...rest } = definition;
6714
+ return {
6715
+ ...rest,
6716
+ resource,
6717
+ resourceId: resource.id,
6718
+ type: resource.kind
6719
+ };
6720
+ }
6348
6721
  DisplayMetadataSchema.extend({
6349
6722
  id: ModelIdSchema,
6350
6723
  order: z.number().min(0)
@@ -7612,6 +7985,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
7612
7985
  },
7613
7986
  ontology: DEFAULT_ONTOLOGY_SCOPE,
7614
7987
  resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
7988
+ topology: DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
7615
7989
  actions: DEFAULT_ORGANIZATION_MODEL_ACTIONS,
7616
7990
  entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES2,
7617
7991
  policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
@@ -8864,4 +9238,4 @@ function isOurReplyAction(deal) {
8864
9238
  var listBuilderStageKeys = Object.keys(LEAD_GEN_STAGE_CATALOG);
8865
9239
  var ListBuilderStageKeySchema = z.enum(listBuilderStageKeys);
8866
9240
 
8867
- export { ActivityEventSchema, BuildPlanSnapshotStepSchema, ProspectingBuildTemplateSchema as BuildTemplateSchema, CRM_PIPELINE_DEFINITION, CrmStageKeySchema, CrmStateKeySchema, DEFAULT_CRM_ACTIONS, EmailSchema, ExecutionError, LEAD_GEN_STAGE_CATALOG, ListBuilderStageKeySchema, ProcessingStageStatusSchema, RegistryValidationError, ResourceRegistry, StepType, ToolingError, deriveActions, validateResourceGovernance };
9241
+ export { ActivityEventSchema, BuildPlanSnapshotStepSchema, ProspectingBuildTemplateSchema as BuildTemplateSchema, CRM_PIPELINE_DEFINITION, CrmStageKeySchema, CrmStateKeySchema, DEFAULT_CRM_ACTIONS, EmailSchema, ExecutionError, LEAD_GEN_STAGE_CATALOG, ListBuilderStageKeySchema, ProcessingStageStatusSchema, RegistryValidationError, ResourceRegistry, StepType, ToolingError, bindResourceDescriptor, defineResource, defineResourceOntology, defineResources, defineTopology, defineTopologyRelationship, deriveActions, parseTopologyNodeRef, topologyRef, topologyRelationship, validateResourceGovernance };