@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.
@@ -8075,7 +8075,6 @@ function addLegacyEntityProjections(index2, diagnostics, sourcesById, entities)
8075
8075
  table: entity.table
8076
8076
  }
8077
8077
  } : {},
8078
- legacyEntityId: entity.id,
8079
8078
  ...entity.rowSchema !== void 0 ? { rowSchema: entity.rowSchema } : {},
8080
8079
  ...entity.stateCatalogId !== void 0 ? { stateCatalogId: entity.stateCatalogId } : {}
8081
8080
  };
@@ -8100,8 +8099,7 @@ function addLegacyEntityProjections(index2, diagnostics, sourcesById, entities)
8100
8099
  from: legacyObjectId(entity),
8101
8100
  to: legacyObjectId(targetEntity),
8102
8101
  cardinality: link.kind,
8103
- ...link.via !== void 0 ? { via: link.via } : {},
8104
- legacyEntityId: entity.id
8102
+ ...link.via !== void 0 ? { via: link.via } : {}
8105
8103
  };
8106
8104
  addRecord(index2, diagnostics, sourcesById, "linkTypes", linkType, {
8107
8105
  source: "legacy.entities.links",
@@ -8159,8 +8157,7 @@ function addSystemContentProjections(index2, diagnostics, sourcesById, systemPat
8159
8157
  kind: node.type,
8160
8158
  ...typeof node.data?.["entityId"] === "string" ? { appliesTo: formatOntologyId({ scope: systemPath, kind: "object", localId: node.data["entityId"] }) } : {},
8161
8159
  ...Object.keys(entries).length > 0 ? { entries } : {},
8162
- ...node.data !== void 0 ? { data: node.data } : {},
8163
- legacyContentId: `${systemPath}:${localId}`
8160
+ ...node.data !== void 0 ? { data: node.data } : {}
8164
8161
  };
8165
8162
  addRecord(index2, diagnostics, sourcesById, "catalogTypes", catalogType, {
8166
8163
  source: "legacy.system.content",
@@ -8338,11 +8335,20 @@ EventEmissionDescriptorSchema.extend({
8338
8335
  ownerKind: z.enum(["resource", "entity"]).meta({ label: "Owner kind" })
8339
8336
  });
8340
8337
  var ResourceOntologyBindingSchema = z.object({
8341
- implements: z.array(OntologyIdSchema).optional(),
8338
+ actions: z.array(OntologyIdSchema).optional(),
8339
+ primaryAction: OntologyIdSchema.optional(),
8342
8340
  reads: z.array(OntologyIdSchema).optional(),
8343
8341
  writes: z.array(OntologyIdSchema).optional(),
8344
8342
  usesCatalogs: z.array(OntologyIdSchema).optional(),
8345
8343
  emits: z.array(OntologyIdSchema).optional()
8344
+ }).superRefine((binding, ctx) => {
8345
+ if (binding.primaryAction === void 0) return;
8346
+ if (binding.actions?.includes(binding.primaryAction)) return;
8347
+ ctx.addIssue({
8348
+ code: z.ZodIssueCode.custom,
8349
+ path: ["primaryAction"],
8350
+ message: "Resource ontology primaryAction must be included in actions"
8351
+ });
8346
8352
  });
8347
8353
  var CodeReferenceSchema = z.object({
8348
8354
  path: z.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
@@ -8357,6 +8363,10 @@ var ResourceEntryBaseSchema = z.object({
8357
8363
  order: z.number().default(0),
8358
8364
  /** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
8359
8365
  systemPath: SystemPathSchema.meta({ ref: "system" }),
8366
+ /** Executable display title owned by the OM Resource descriptor. */
8367
+ title: LabelSchema.optional(),
8368
+ /** Executable display description owned by the OM Resource descriptor. */
8369
+ description: DescriptionSchema.optional(),
8360
8370
  /** Optional role responsible for maintaining this resource. */
8361
8371
  ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
8362
8372
  status: ResourceGovernanceStatusSchema,
@@ -8371,8 +8381,6 @@ var ResourceEntryBaseSchema = z.object({
8371
8381
  });
8372
8382
  var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
8373
8383
  kind: z.literal("workflow"),
8374
- /** Mirrors WorkflowConfig.actionKey when the runtime workflow has one. */
8375
- actionKey: z.string().trim().min(1).max(255).optional(),
8376
8384
  emits: z.array(EventEmissionDescriptorSchema).optional()
8377
8385
  });
8378
8386
  var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
@@ -8514,6 +8522,73 @@ var GoalsDomainSchema = z.record(z.string(), ObjectiveSchema).refine((record) =>
8514
8522
  message: "Each objective entry id must match its map key"
8515
8523
  }).default({});
8516
8524
  var DEFAULT_ORGANIZATION_MODEL_GOALS = {};
8525
+ var SecretLikeMetadataKeySchema = /(?:secret|password|passwd|token|api[-_]?key|credential|private[-_]?key)/i;
8526
+ 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-----)/;
8527
+ z.enum([
8528
+ "system",
8529
+ "resource",
8530
+ "ontology",
8531
+ "policy",
8532
+ "role",
8533
+ "trigger",
8534
+ "humanCheckpoint",
8535
+ "externalResource"
8536
+ ]);
8537
+ var OmTopologyRelationshipKindSchema = z.enum(["triggers", "uses", "approval"]);
8538
+ var OmTopologyNodeRefSchema = z.discriminatedUnion("kind", [
8539
+ z.object({ kind: z.literal("system"), id: ModelIdSchema }),
8540
+ z.object({ kind: z.literal("resource"), id: ResourceIdSchema }),
8541
+ z.object({ kind: z.literal("ontology"), id: OntologyIdSchema }),
8542
+ z.object({ kind: z.literal("policy"), id: ModelIdSchema }),
8543
+ z.object({ kind: z.literal("role"), id: ModelIdSchema }),
8544
+ z.object({ kind: z.literal("trigger"), id: ResourceIdSchema }),
8545
+ z.object({ kind: z.literal("humanCheckpoint"), id: ResourceIdSchema }),
8546
+ z.object({ kind: z.literal("externalResource"), id: ResourceIdSchema })
8547
+ ]);
8548
+ var OmTopologyMetadataSchema = z.record(z.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
8549
+ function visit(value, path) {
8550
+ if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
8551
+ ctx.addIssue({
8552
+ code: z.ZodIssueCode.custom,
8553
+ path,
8554
+ message: "Topology metadata must not contain secret-like values"
8555
+ });
8556
+ return;
8557
+ }
8558
+ if (Array.isArray(value)) {
8559
+ value.forEach((entry, index2) => visit(entry, [...path, index2]));
8560
+ return;
8561
+ }
8562
+ if (typeof value !== "object" || value === null) return;
8563
+ Object.entries(value).forEach(([key, entry]) => {
8564
+ if (SecretLikeMetadataKeySchema.test(key)) {
8565
+ ctx.addIssue({
8566
+ code: z.ZodIssueCode.custom,
8567
+ path: [...path, key],
8568
+ message: `Topology metadata key "${key}" looks secret-like`
8569
+ });
8570
+ }
8571
+ visit(entry, [...path, key]);
8572
+ });
8573
+ }
8574
+ visit(metadata, []);
8575
+ });
8576
+ var OmTopologyRelationshipSchema = z.object({
8577
+ from: OmTopologyNodeRefSchema,
8578
+ kind: OmTopologyRelationshipKindSchema,
8579
+ to: OmTopologyNodeRefSchema,
8580
+ systemPath: SystemPathSchema.optional(),
8581
+ required: z.boolean().optional(),
8582
+ metadata: OmTopologyMetadataSchema.optional()
8583
+ });
8584
+ var OmTopologyDomainSchema = z.object({
8585
+ version: z.literal(1).default(1),
8586
+ relationships: z.record(z.string().trim().min(1).max(255), OmTopologyRelationshipSchema).default({})
8587
+ }).default({ version: 1, relationships: {} });
8588
+ var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
8589
+ version: 1,
8590
+ relationships: {}
8591
+ };
8517
8592
  var PolicyIdSchema = ModelIdSchema;
8518
8593
  var PolicyApplicabilitySchema = z.object({
8519
8594
  systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
@@ -8886,6 +8961,7 @@ z.enum([
8886
8961
  "systems",
8887
8962
  "ontology",
8888
8963
  "resources",
8964
+ "topology",
8889
8965
  "actions",
8890
8966
  "entities",
8891
8967
  "policies",
@@ -8905,6 +8981,7 @@ var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
8905
8981
  systems: { version: 1, lastModified: "2026-05-10" },
8906
8982
  ontology: { version: 1, lastModified: "2026-05-14" },
8907
8983
  resources: { version: 1, lastModified: "2026-05-10" },
8984
+ topology: { version: 1, lastModified: "2026-05-14" },
8908
8985
  actions: { version: 1, lastModified: "2026-05-10" },
8909
8986
  entities: { version: 1, lastModified: "2026-05-10" },
8910
8987
  policies: { version: 1, lastModified: "2026-05-10" },
@@ -8920,6 +8997,7 @@ var OrganizationModelDomainMetadataByDomainSchema = z.object({
8920
8997
  systems: OrganizationModelDomainMetadataSchema,
8921
8998
  ontology: OrganizationModelDomainMetadataSchema,
8922
8999
  resources: OrganizationModelDomainMetadataSchema,
9000
+ topology: OrganizationModelDomainMetadataSchema,
8923
9001
  actions: OrganizationModelDomainMetadataSchema,
8924
9002
  entities: OrganizationModelDomainMetadataSchema,
8925
9003
  policies: OrganizationModelDomainMetadataSchema,
@@ -8938,6 +9016,7 @@ var OrganizationModelSchemaBase = z.object({
8938
9016
  systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
8939
9017
  ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
8940
9018
  resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
9019
+ topology: OmTopologyDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_TOPOLOGY),
8941
9020
  actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
8942
9021
  entities: EntitiesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ENTITIES),
8943
9022
  policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
@@ -9280,6 +9359,25 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
9280
9359
  surface: ontologyCompilation.ontology.surfaces
9281
9360
  };
9282
9361
  const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index2) => Object.keys(index2)));
9362
+ function topologyTargetExists(ref) {
9363
+ if (ref.kind === "system") return systemsById.has(ref.id);
9364
+ if (ref.kind === "resource") return resourcesById.has(ref.id);
9365
+ if (ref.kind === "ontology") return ontologyIds.has(ref.id);
9366
+ if (ref.kind === "policy") return policiesById.has(ref.id);
9367
+ if (ref.kind === "role") return rolesById.has(ref.id);
9368
+ return true;
9369
+ }
9370
+ Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
9371
+ ["from", "to"].forEach((side) => {
9372
+ const ref = relationship[side];
9373
+ if (topologyTargetExists(ref)) return;
9374
+ addIssue(
9375
+ ctx,
9376
+ ["topology", "relationships", relationshipId, side],
9377
+ `Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
9378
+ );
9379
+ });
9380
+ });
9283
9381
  const ontologyReferenceKeyKinds = {
9284
9382
  valueType: "value-type",
9285
9383
  catalogType: "catalog",
@@ -9418,11 +9516,18 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
9418
9516
  }
9419
9517
  });
9420
9518
  function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
9421
- ids?.forEach((ontologyId, ontologyIndex) => {
9519
+ const ontologyIds2 = ids === void 0 ? [] : Array.isArray(ids) ? ids : [ids];
9520
+ ontologyIds2.forEach((ontologyId, ontologyIndex) => {
9422
9521
  if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
9423
9522
  addIssue(
9424
9523
  ctx,
9425
- ["resources", resourceId, "ontology", bindingKey, ontologyIndex],
9524
+ [
9525
+ "resources",
9526
+ resourceId,
9527
+ "ontology",
9528
+ bindingKey,
9529
+ ...Array.isArray(ids) ? [ontologyIndex] : []
9530
+ ],
9426
9531
  `Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
9427
9532
  );
9428
9533
  }
@@ -9431,7 +9536,8 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
9431
9536
  Object.values(model.resources).forEach((resource) => {
9432
9537
  const binding = resource.ontology;
9433
9538
  if (binding === void 0) return;
9434
- validateResourceOntologyBinding(resource.id, "implements", "action", binding.implements);
9539
+ validateResourceOntologyBinding(resource.id, "actions", "action", binding.actions);
9540
+ validateResourceOntologyBinding(resource.id, "primaryAction", "action", binding.primaryAction);
9435
9541
  validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
9436
9542
  validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
9437
9543
  validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
@@ -10260,6 +10366,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
10260
10366
  },
10261
10367
  ontology: DEFAULT_ONTOLOGY_SCOPE,
10262
10368
  resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
10369
+ topology: DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
10263
10370
  actions: DEFAULT_ORGANIZATION_MODEL_ACTIONS,
10264
10371
  entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES2,
10265
10372
  policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
@@ -11731,6 +11838,119 @@ function getRuntimeResources(resources) {
11731
11838
  }))
11732
11839
  ];
11733
11840
  }
11841
+ function hasOntologySources(organizationModel) {
11842
+ return organizationModel.ontology !== void 0 || organizationModel.entities !== void 0 || organizationModel.actions !== void 0 || Object.values(organizationModel.systems ?? {}).some(systemHasOntologySource);
11843
+ }
11844
+ function systemHasOntologySource(system) {
11845
+ if (system.ontology !== void 0 || system.content !== void 0 && Object.keys(system.content).length > 0) return true;
11846
+ return Object.values(system.systems ?? system.subsystems ?? {}).some(systemHasOntologySource);
11847
+ }
11848
+ function ontologyIndexForKind(index2, kind) {
11849
+ switch (kind) {
11850
+ case "object":
11851
+ return index2.objectTypes;
11852
+ case "link":
11853
+ return index2.linkTypes;
11854
+ case "action":
11855
+ return index2.actionTypes;
11856
+ case "catalog":
11857
+ return index2.catalogTypes;
11858
+ case "event":
11859
+ return index2.eventTypes;
11860
+ case "interface":
11861
+ return index2.interfaceTypes;
11862
+ case "value-type":
11863
+ return index2.valueTypes;
11864
+ case "property":
11865
+ return index2.sharedProperties;
11866
+ case "group":
11867
+ return index2.groups;
11868
+ case "surface":
11869
+ return index2.surfaces;
11870
+ }
11871
+ }
11872
+ function sameJson(left, right) {
11873
+ return JSON.stringify(left ?? null) === JSON.stringify(right ?? null);
11874
+ }
11875
+ function addOntologyBindingIssues(issues, orgName, resource, ontologyIndex) {
11876
+ const binding = resource.ontology;
11877
+ if (binding === void 0) return;
11878
+ if ((resource.kind === "workflow" || resource.kind === "agent") && (binding.actions?.length ?? 0) === 0) {
11879
+ addGovernanceIssue(
11880
+ issues,
11881
+ "missing-ontology-actions",
11882
+ orgName,
11883
+ resource.id,
11884
+ `[${orgName}] Resource '${resource.id}' declares ontology bindings but no ontology actions.`
11885
+ );
11886
+ }
11887
+ if (binding.primaryAction !== void 0 && !binding.actions?.includes(binding.primaryAction)) {
11888
+ addGovernanceIssue(
11889
+ issues,
11890
+ "primary-action-mismatch",
11891
+ orgName,
11892
+ resource.id,
11893
+ `[${orgName}] Resource '${resource.id}' primaryAction '${binding.primaryAction}' must be included in ontology.actions.`
11894
+ );
11895
+ }
11896
+ if (ontologyIndex === void 0) return;
11897
+ const validateRefs = (bindingKey, expectedKind, refs) => {
11898
+ const values = refs === void 0 ? [] : Array.isArray(refs) ? refs : [refs];
11899
+ const index2 = ontologyIndexForKind(ontologyIndex, expectedKind);
11900
+ for (const ref of values) {
11901
+ if (index2[ref] !== void 0) continue;
11902
+ addGovernanceIssue(
11903
+ issues,
11904
+ "ontology-reference-missing",
11905
+ orgName,
11906
+ resource.id,
11907
+ `[${orgName}] Resource '${resource.id}' ontology.${bindingKey} references missing ${expectedKind} ontology record '${ref}'.`
11908
+ );
11909
+ }
11910
+ };
11911
+ validateRefs("actions", "action", binding.actions);
11912
+ validateRefs("primaryAction", "action", binding.primaryAction);
11913
+ validateRefs("reads", "object", binding.reads);
11914
+ validateRefs("writes", "object", binding.writes);
11915
+ validateRefs("usesCatalogs", "catalog", binding.usesCatalogs);
11916
+ validateRefs("emits", "event", binding.emits);
11917
+ }
11918
+ function addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex) {
11919
+ const relationships = organizationModel.topology?.relationships;
11920
+ if (relationships === void 0) return;
11921
+ const rolesById = new Set(Object.keys(organizationModel.roles ?? {}));
11922
+ const policiesById = new Set(Object.keys(organizationModel.policies ?? {}));
11923
+ const triggerIds = new Set(deployment.triggers?.map((trigger) => trigger.resourceId) ?? []);
11924
+ const humanCheckpointIds = new Set(deployment.humanCheckpoints?.map((checkpoint) => checkpoint.resourceId) ?? []);
11925
+ const externalResourceIds = new Set(deployment.externalResources?.map((external) => external.resourceId) ?? []);
11926
+ const topologyRefExists = (ref) => {
11927
+ if (ref.kind === "system") return systemsById.has(ref.id);
11928
+ if (ref.kind === "resource") return omResourcesById.has(ref.id);
11929
+ if (ref.kind === "policy") return policiesById.has(ref.id);
11930
+ if (ref.kind === "role") return rolesById.has(ref.id);
11931
+ if (ref.kind === "trigger") return triggerIds.has(ref.id);
11932
+ if (ref.kind === "humanCheckpoint") return humanCheckpointIds.has(ref.id);
11933
+ if (ref.kind === "externalResource") return externalResourceIds.has(ref.id);
11934
+ if (ref.kind === "ontology") {
11935
+ if (ontologyIndex === void 0) return true;
11936
+ return Object.values(ontologyIndex).some((records) => records[ref.id] !== void 0);
11937
+ }
11938
+ return false;
11939
+ };
11940
+ for (const [relationshipId, relationship] of Object.entries(relationships)) {
11941
+ ["from", "to"].forEach((side) => {
11942
+ const ref = relationship[side];
11943
+ if (topologyRefExists(ref)) return;
11944
+ addGovernanceIssue(
11945
+ issues,
11946
+ "topology-reference-missing",
11947
+ orgName,
11948
+ ref.id,
11949
+ `[${orgName}] Topology relationship '${relationshipId}' ${side} references missing ${ref.kind} '${ref.id}'.`
11950
+ );
11951
+ });
11952
+ }
11953
+ }
11734
11954
  function validateResourceGovernance(orgName, deployment, organizationModel = deployment.organizationModel, options = {}) {
11735
11955
  const mode = getResourceValidatorMode(options.mode);
11736
11956
  const omResourcesMap = organizationModel?.resources;
@@ -11746,6 +11966,17 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
11746
11966
  const omResourcesById = new Map(activeOmResources.map((resource) => [resource.id, resource]));
11747
11967
  const runtimeResources = getRuntimeResources(deployment);
11748
11968
  const runtimeResourcesById = new Map(runtimeResources.map((resource) => [resource.resourceId, resource]));
11969
+ const ontologyCompilation = hasOntologySources(organizationModel) ? compileOrganizationOntology(organizationModel) : void 0;
11970
+ const ontologyIndex = ontologyCompilation?.ontology;
11971
+ for (const diagnostic of ontologyCompilation?.diagnostics ?? []) {
11972
+ addGovernanceIssue(
11973
+ issues,
11974
+ "ontology-reference-missing",
11975
+ orgName,
11976
+ diagnostic.id,
11977
+ `[${orgName}] ${diagnostic.message}`
11978
+ );
11979
+ }
11749
11980
  for (const resource of activeOmResources) {
11750
11981
  if (!systemsById.has(resource.systemPath)) {
11751
11982
  addGovernanceIssue(
@@ -11785,6 +12016,16 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
11785
12016
  `[${orgName}] Resource '${resource.id}' system mismatch: code descriptor has '${runtimeResource.descriptor.systemPath}', OM has '${resource.systemPath}'.`
11786
12017
  );
11787
12018
  }
12019
+ if (runtimeResource.descriptor && !sameJson(runtimeResource.descriptor.ontology, resource.ontology)) {
12020
+ addGovernanceIssue(
12021
+ issues,
12022
+ "descriptor-mismatch",
12023
+ orgName,
12024
+ resource.id,
12025
+ `[${orgName}] Resource '${resource.id}' ontology descriptor mismatch between code and OM.`
12026
+ );
12027
+ }
12028
+ addOntologyBindingIssues(issues, orgName, resource, ontologyIndex);
11788
12029
  }
11789
12030
  for (const runtimeResource of runtimeResources) {
11790
12031
  const omResource = omResourcesById.get(runtimeResource.resourceId);
@@ -11826,6 +12067,7 @@ function validateResourceGovernance(orgName, deployment, organizationModel = dep
11826
12067
  );
11827
12068
  }
11828
12069
  }
12070
+ addTopologyIssues(issues, orgName, deployment, organizationModel, systemsById, omResourcesById, ontologyIndex);
11829
12071
  emitGovernanceIssues(issues, mode, options.onWarning);
11830
12072
  return {
11831
12073
  valid: issues.length === 0,
@@ -6167,7 +6167,6 @@ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
6167
6167
  table: entity.table
6168
6168
  }
6169
6169
  } : {},
6170
- legacyEntityId: entity.id,
6171
6170
  ...entity.rowSchema !== void 0 ? { rowSchema: entity.rowSchema } : {},
6172
6171
  ...entity.stateCatalogId !== void 0 ? { stateCatalogId: entity.stateCatalogId } : {}
6173
6172
  };
@@ -6192,8 +6191,7 @@ function addLegacyEntityProjections(index, diagnostics, sourcesById, entities) {
6192
6191
  from: legacyObjectId(entity),
6193
6192
  to: legacyObjectId(targetEntity),
6194
6193
  cardinality: link.kind,
6195
- ...link.via !== void 0 ? { via: link.via } : {},
6196
- legacyEntityId: entity.id
6194
+ ...link.via !== void 0 ? { via: link.via } : {}
6197
6195
  };
6198
6196
  addRecord(index, diagnostics, sourcesById, "linkTypes", linkType, {
6199
6197
  source: "legacy.entities.links",
@@ -6251,8 +6249,7 @@ function addSystemContentProjections(index, diagnostics, sourcesById, systemPath
6251
6249
  kind: node.type,
6252
6250
  ...typeof node.data?.["entityId"] === "string" ? { appliesTo: formatOntologyId({ scope: systemPath, kind: "object", localId: node.data["entityId"] }) } : {},
6253
6251
  ...Object.keys(entries).length > 0 ? { entries } : {},
6254
- ...node.data !== void 0 ? { data: node.data } : {},
6255
- legacyContentId: `${systemPath}:${localId}`
6252
+ ...node.data !== void 0 ? { data: node.data } : {}
6256
6253
  };
6257
6254
  addRecord(index, diagnostics, sourcesById, "catalogTypes", catalogType, {
6258
6255
  source: "legacy.system.content",
@@ -6430,11 +6427,20 @@ EventEmissionDescriptorSchema.extend({
6430
6427
  ownerKind: z.enum(["resource", "entity"]).meta({ label: "Owner kind" })
6431
6428
  });
6432
6429
  var ResourceOntologyBindingSchema = z.object({
6433
- implements: z.array(OntologyIdSchema).optional(),
6430
+ actions: z.array(OntologyIdSchema).optional(),
6431
+ primaryAction: OntologyIdSchema.optional(),
6434
6432
  reads: z.array(OntologyIdSchema).optional(),
6435
6433
  writes: z.array(OntologyIdSchema).optional(),
6436
6434
  usesCatalogs: z.array(OntologyIdSchema).optional(),
6437
6435
  emits: z.array(OntologyIdSchema).optional()
6436
+ }).superRefine((binding, ctx) => {
6437
+ if (binding.primaryAction === void 0) return;
6438
+ if (binding.actions?.includes(binding.primaryAction)) return;
6439
+ ctx.addIssue({
6440
+ code: z.ZodIssueCode.custom,
6441
+ path: ["primaryAction"],
6442
+ message: "Resource ontology primaryAction must be included in actions"
6443
+ });
6438
6444
  });
6439
6445
  var CodeReferenceSchema = z.object({
6440
6446
  path: z.string().trim().min(1).max(500).regex(/^[A-Za-z0-9_./$@()[\] -]+$/, "Code reference paths must be repo-relative paths"),
@@ -6449,6 +6455,10 @@ var ResourceEntryBaseSchema = z.object({
6449
6455
  order: z.number().default(0),
6450
6456
  /** Required single System membership — value is a dot-separated system path (e.g. "sales.lead-gen"). */
6451
6457
  systemPath: SystemPathSchema.meta({ ref: "system" }),
6458
+ /** Executable display title owned by the OM Resource descriptor. */
6459
+ title: LabelSchema.optional(),
6460
+ /** Executable display description owned by the OM Resource descriptor. */
6461
+ description: DescriptionSchema.optional(),
6452
6462
  /** Optional role responsible for maintaining this resource. */
6453
6463
  ownerRoleId: ModelIdSchema.meta({ ref: "role" }).optional(),
6454
6464
  status: ResourceGovernanceStatusSchema,
@@ -6463,8 +6473,6 @@ var ResourceEntryBaseSchema = z.object({
6463
6473
  });
6464
6474
  var WorkflowResourceEntrySchema = ResourceEntryBaseSchema.extend({
6465
6475
  kind: z.literal("workflow"),
6466
- /** Mirrors WorkflowConfig.actionKey when the runtime workflow has one. */
6467
- actionKey: z.string().trim().min(1).max(255).optional(),
6468
6476
  emits: z.array(EventEmissionDescriptorSchema).optional()
6469
6477
  });
6470
6478
  var AgentResourceEntrySchema = ResourceEntryBaseSchema.extend({
@@ -6606,6 +6614,73 @@ var GoalsDomainSchema = z.record(z.string(), ObjectiveSchema).refine((record) =>
6606
6614
  message: "Each objective entry id must match its map key"
6607
6615
  }).default({});
6608
6616
  var DEFAULT_ORGANIZATION_MODEL_GOALS = {};
6617
+ var SecretLikeMetadataKeySchema = /(?:secret|password|passwd|token|api[-_]?key|credential|private[-_]?key)/i;
6618
+ 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-----)/;
6619
+ z.enum([
6620
+ "system",
6621
+ "resource",
6622
+ "ontology",
6623
+ "policy",
6624
+ "role",
6625
+ "trigger",
6626
+ "humanCheckpoint",
6627
+ "externalResource"
6628
+ ]);
6629
+ var OmTopologyRelationshipKindSchema = z.enum(["triggers", "uses", "approval"]);
6630
+ var OmTopologyNodeRefSchema = z.discriminatedUnion("kind", [
6631
+ z.object({ kind: z.literal("system"), id: ModelIdSchema }),
6632
+ z.object({ kind: z.literal("resource"), id: ResourceIdSchema }),
6633
+ z.object({ kind: z.literal("ontology"), id: OntologyIdSchema }),
6634
+ z.object({ kind: z.literal("policy"), id: ModelIdSchema }),
6635
+ z.object({ kind: z.literal("role"), id: ModelIdSchema }),
6636
+ z.object({ kind: z.literal("trigger"), id: ResourceIdSchema }),
6637
+ z.object({ kind: z.literal("humanCheckpoint"), id: ResourceIdSchema }),
6638
+ z.object({ kind: z.literal("externalResource"), id: ResourceIdSchema })
6639
+ ]);
6640
+ var OmTopologyMetadataSchema = z.record(z.string().trim().min(1).max(120), JsonValueSchema).superRefine((metadata, ctx) => {
6641
+ function visit(value, path) {
6642
+ if (typeof value === "string" && SecretLikeMetadataValueSchema.test(value)) {
6643
+ ctx.addIssue({
6644
+ code: z.ZodIssueCode.custom,
6645
+ path,
6646
+ message: "Topology metadata must not contain secret-like values"
6647
+ });
6648
+ return;
6649
+ }
6650
+ if (Array.isArray(value)) {
6651
+ value.forEach((entry, index) => visit(entry, [...path, index]));
6652
+ return;
6653
+ }
6654
+ if (typeof value !== "object" || value === null) return;
6655
+ Object.entries(value).forEach(([key, entry]) => {
6656
+ if (SecretLikeMetadataKeySchema.test(key)) {
6657
+ ctx.addIssue({
6658
+ code: z.ZodIssueCode.custom,
6659
+ path: [...path, key],
6660
+ message: `Topology metadata key "${key}" looks secret-like`
6661
+ });
6662
+ }
6663
+ visit(entry, [...path, key]);
6664
+ });
6665
+ }
6666
+ visit(metadata, []);
6667
+ });
6668
+ var OmTopologyRelationshipSchema = z.object({
6669
+ from: OmTopologyNodeRefSchema,
6670
+ kind: OmTopologyRelationshipKindSchema,
6671
+ to: OmTopologyNodeRefSchema,
6672
+ systemPath: SystemPathSchema.optional(),
6673
+ required: z.boolean().optional(),
6674
+ metadata: OmTopologyMetadataSchema.optional()
6675
+ });
6676
+ var OmTopologyDomainSchema = z.object({
6677
+ version: z.literal(1).default(1),
6678
+ relationships: z.record(z.string().trim().min(1).max(255), OmTopologyRelationshipSchema).default({})
6679
+ }).default({ version: 1, relationships: {} });
6680
+ var DEFAULT_ORGANIZATION_MODEL_TOPOLOGY = {
6681
+ version: 1,
6682
+ relationships: {}
6683
+ };
6609
6684
  var PolicyIdSchema = ModelIdSchema;
6610
6685
  var PolicyApplicabilitySchema = z.object({
6611
6686
  systemIds: z.array(ModelIdSchema.meta({ ref: "system" })).default([]),
@@ -6978,6 +7053,7 @@ z.enum([
6978
7053
  "systems",
6979
7054
  "ontology",
6980
7055
  "resources",
7056
+ "topology",
6981
7057
  "actions",
6982
7058
  "entities",
6983
7059
  "policies",
@@ -6997,6 +7073,7 @@ var DEFAULT_ORGANIZATION_MODEL_DOMAIN_METADATA = {
6997
7073
  systems: { version: 1, lastModified: "2026-05-10" },
6998
7074
  ontology: { version: 1, lastModified: "2026-05-14" },
6999
7075
  resources: { version: 1, lastModified: "2026-05-10" },
7076
+ topology: { version: 1, lastModified: "2026-05-14" },
7000
7077
  actions: { version: 1, lastModified: "2026-05-10" },
7001
7078
  entities: { version: 1, lastModified: "2026-05-10" },
7002
7079
  policies: { version: 1, lastModified: "2026-05-10" },
@@ -7012,6 +7089,7 @@ var OrganizationModelDomainMetadataByDomainSchema = z.object({
7012
7089
  systems: OrganizationModelDomainMetadataSchema,
7013
7090
  ontology: OrganizationModelDomainMetadataSchema,
7014
7091
  resources: OrganizationModelDomainMetadataSchema,
7092
+ topology: OrganizationModelDomainMetadataSchema,
7015
7093
  actions: OrganizationModelDomainMetadataSchema,
7016
7094
  entities: OrganizationModelDomainMetadataSchema,
7017
7095
  policies: OrganizationModelDomainMetadataSchema,
@@ -7030,6 +7108,7 @@ var OrganizationModelSchemaBase = z.object({
7030
7108
  systems: SystemsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_SYSTEMS),
7031
7109
  ontology: OntologyScopeSchema.default(DEFAULT_ONTOLOGY_SCOPE),
7032
7110
  resources: ResourcesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_RESOURCES),
7111
+ topology: OmTopologyDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_TOPOLOGY),
7033
7112
  actions: ActionsDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ACTIONS),
7034
7113
  entities: EntitiesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_ENTITIES),
7035
7114
  policies: PoliciesDomainSchema.default(DEFAULT_ORGANIZATION_MODEL_POLICIES),
@@ -7372,6 +7451,25 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
7372
7451
  surface: ontologyCompilation.ontology.surfaces
7373
7452
  };
7374
7453
  const ontologyIds = new Set(Object.values(ontologyIndexByKind).flatMap((index) => Object.keys(index)));
7454
+ function topologyTargetExists(ref) {
7455
+ if (ref.kind === "system") return systemsById.has(ref.id);
7456
+ if (ref.kind === "resource") return resourcesById.has(ref.id);
7457
+ if (ref.kind === "ontology") return ontologyIds.has(ref.id);
7458
+ if (ref.kind === "policy") return policiesById.has(ref.id);
7459
+ if (ref.kind === "role") return rolesById.has(ref.id);
7460
+ return true;
7461
+ }
7462
+ Object.entries(model.topology.relationships).forEach(([relationshipId, relationship]) => {
7463
+ ["from", "to"].forEach((side) => {
7464
+ const ref = relationship[side];
7465
+ if (topologyTargetExists(ref)) return;
7466
+ addIssue(
7467
+ ctx,
7468
+ ["topology", "relationships", relationshipId, side],
7469
+ `Topology relationship "${relationshipId}" ${side} references unknown ${ref.kind} "${ref.id}"`
7470
+ );
7471
+ });
7472
+ });
7375
7473
  const ontologyReferenceKeyKinds = {
7376
7474
  valueType: "value-type",
7377
7475
  catalogType: "catalog",
@@ -7510,11 +7608,18 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
7510
7608
  }
7511
7609
  });
7512
7610
  function validateResourceOntologyBinding(resourceId, bindingKey, expectedKind, ids) {
7513
- ids?.forEach((ontologyId, ontologyIndex) => {
7611
+ const ontologyIds2 = ids === void 0 ? [] : Array.isArray(ids) ? ids : [ids];
7612
+ ontologyIds2.forEach((ontologyId, ontologyIndex) => {
7514
7613
  if (ontologyIndexByKind[expectedKind][ontologyId] === void 0) {
7515
7614
  addIssue(
7516
7615
  ctx,
7517
- ["resources", resourceId, "ontology", bindingKey, ontologyIndex],
7616
+ [
7617
+ "resources",
7618
+ resourceId,
7619
+ "ontology",
7620
+ bindingKey,
7621
+ ...Array.isArray(ids) ? [ontologyIndex] : []
7622
+ ],
7518
7623
  `Resource "${resourceId}" ontology binding "${bindingKey}" references unknown ${expectedKind} ontology ID "${ontologyId}"`
7519
7624
  );
7520
7625
  }
@@ -7523,7 +7628,8 @@ OrganizationModelSchemaBase.superRefine((model, ctx) => {
7523
7628
  Object.values(model.resources).forEach((resource) => {
7524
7629
  const binding = resource.ontology;
7525
7630
  if (binding === void 0) return;
7526
- validateResourceOntologyBinding(resource.id, "implements", "action", binding.implements);
7631
+ validateResourceOntologyBinding(resource.id, "actions", "action", binding.actions);
7632
+ validateResourceOntologyBinding(resource.id, "primaryAction", "action", binding.primaryAction);
7527
7633
  validateResourceOntologyBinding(resource.id, "reads", "object", binding.reads);
7528
7634
  validateResourceOntologyBinding(resource.id, "writes", "object", binding.writes);
7529
7635
  validateResourceOntologyBinding(resource.id, "usesCatalogs", "catalog", binding.usesCatalogs);
@@ -8352,6 +8458,7 @@ var DEFAULT_ORGANIZATION_MODEL = {
8352
8458
  },
8353
8459
  ontology: DEFAULT_ONTOLOGY_SCOPE,
8354
8460
  resources: DEFAULT_ORGANIZATION_MODEL_RESOURCES,
8461
+ topology: DEFAULT_ORGANIZATION_MODEL_TOPOLOGY,
8355
8462
  actions: DEFAULT_ORGANIZATION_MODEL_ACTIONS,
8356
8463
  entities: DEFAULT_ORGANIZATION_MODEL_ENTITIES2,
8357
8464
  policies: DEFAULT_ORGANIZATION_MODEL_POLICIES,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elevasis/sdk",
3
- "version": "1.22.0",
3
+ "version": "1.22.1",
4
4
  "description": "SDK for building Elevasis organization resources",
5
5
  "type": "module",
6
6
  "bin": {
@@ -57,9 +57,9 @@
57
57
  "tsup": "^8.0.0",
58
58
  "typescript": "5.9.2",
59
59
  "zod": "^4.1.0",
60
- "@repo/eslint-config": "0.0.0",
60
+ "@repo/core": "0.24.1",
61
61
  "@repo/typescript-config": "0.0.0",
62
- "@repo/core": "0.24.0"
62
+ "@repo/eslint-config": "0.0.0"
63
63
  },
64
64
  "scripts": {
65
65
  "lint": "eslint src --max-warnings 0",